php抓取网页匹配url(区分和搞清楚每个函数真正的用处-乐题库)
优采云 发布时间: 2022-02-10 13:00php抓取网页匹配url(区分和搞清楚每个函数真正的用处-乐题库)
在日常业务开发过程中,我们经常会有处理URL链接的需求,所以今天学习的功能其实是大家经常用到的一些功能。在之前的工作过程中,其实我对这些功能只是一个模糊的概念,我知道,但是当我真的需要使用它的时候,我还是需要阅读文档来确定我真正要使用哪个功能。因此,今天我们将其作为一个复习练习,主要是为了区分和弄清楚每个功能的真实用途。
编码运算函数
首先要看的是与 URL 编码相关的函数。有些浏览器会在我们复制粘贴后自动对 URL 进行 URL 编码,也就是很多百分号的形式。在 PHP 中,也有相应的编*敏*感*词*函数。
$url = "https://www.zyblog.net?opt=dev&mail=zyblog@net.net&comments=aaa bbb ccc %dfg &==*() cdg&value=“中文也有呀,还有中文符号!!”";
echo $url, PHP_EOL;
// https://www.zyblog.net?opt=dev&mail=zyblog@net.net&comments=aaa bbb ccc %dfg &==*() cdg&value=“中文也有呀,还有中文符号!!”
$enurl = urlencode($url);
echo $enurl, PHP_EOL;
// https%3A%2F%2Fwww.zyblog.net%3Fopt%3Ddev%26mail%3Dzyblog%40net.net%26comments%3Daaa+bbb+ccc+%25dfg+%26%3D%3D%2A%28%29+cdg%26value%3D%E2%80%9C%E4%B8%AD%E6%96%87%E4%B9%9F%E6%9C%89%E5%91%80%EF%BC%8C%E8%BF%98%E6%9C%89%E4%B8%AD%E6%96%87%E7%AC%A6%E5%8F%B7%EF%BC%81%EF%BC%81%E2%80%9D
echo urldecode($enurl), PHP_EOL;
// https://www.zyblog.net?opt=dev&mail=zyblog@net.net&comments=aaa bbb ccc %dfg &==*() cdg&value=“中文也有呀,还有中文符号!!”
这两个函数估计是最常用的函数。urlencode() 是 URL 的编码操作。如您所见,我们准备的链接已被编码为收录各种百分号的内容。尤其是汉字,如果链接中的中文参数是GET方法,编码后的内容会使链接很长。urldecode() 是对应解码函数的函数,可以将编码后的链接解码回原来的状态。
$rawenurl = rawurlencode($enurl);
echo $rawenurl, PHP_EOL;
// https%253A%252F%252Fwww.zyblog.net%253Fopt%253Ddev%2526mail%253Dzyblog%2540net.net%2526comments%253Daaa%2Bbbb%2Bccc%2B%2525dfg%2B%2526%253D%253D%252A%2528%2529%2Bcdg%2526value%253D%25E2%2580%259C%25E4%25B8%25AD%25E6%2596%2587%25E4%25B9%259F%25E6%259C%2589%25E5%2591%2580%25EF%25BC%258C%25E8%25BF%2598%25E6%259C%2589%25E4%25B8%25AD%25E6%2596%2587%25E7%25AC%25A6%25E5%258F%25B7%25EF%25BC%2581%25EF%25BC%2581%25E2%2580%259D
echo rawurldecode($rawenurl), PHP_EOL;
// https%3A%2F%2Fwww.zyblog.net%3Fopt%3Ddev%26mail%3Dzyblog%40net.net%26comments%3Daaa+bbb+ccc+%25dfg+%26%3D%3D%2A%28%29+cdg%26value%3D%E2%80%9C%E4%B8%AD%E6%96%87%E4%B9%9F%E6%9C%89%E5%91%80%EF%BC%8C%E8%BF%98%E6%9C%89%E4%B8%AD%E6%96%87%E7%AC%A6%E5%8F%B7%EF%BC%81%EF%BC%81%E2%80%9D
echo rawurlencode($url), PHP_EOL;
// https%3A%2F%2Fwww.zyblog.net%3Fopt%3Ddev%26mail%3Dzyblog%40net.net%26comments%3Daaa%20bbb%20ccc%20%25dfg%20%26%3D%3D%2A%28%29%20cdg%26value%3D%E2%80%9C%E4%B8%AD%E6%96%87%E4%B9%9F%E6%9C%89%E5%91%80%EF%BC%8C%E8%BF%98%E6%9C%89%E4%B8%AD%E6%96%87%E7%AC%A6%E5%8F%B7%EF%BC%81%EF%BC%81%E2%80%9D
echo rawurldecode($enurl), PHP_EOL;
// https://www.zyblog.net?opt=dev&mail=zyblog@net.net&comments=aaa+bbb+ccc+%dfg+&==*()+cdg&value=“中文也有呀,还有中文符号!!”
接下来我们看到 rawurlencode() 和 rawurldecode()。很多小伙伴都会对它们与普通的urlencode()和urldecode()的区别感到困惑。其实它们的区别主要体现在一些特殊字符上,比如空格。在 urlencode() 中,空格编码为 + 号,在 urlrawencode() 中,空格为 %20。这可以在我们的第三个测试代码中看到。
前两段测试代码对先前编码的 \$enurl 进行操作。第三个测试代码是原创$url的编码。这两个函数是实现 RFC3986 规范的函数。并且 urlencode() 出于历史原因保留了一些特殊情况,例如空格到 + 符号。
最后,我们来看两个非常简单的 Base64 相关的编*敏*感*词*函数。
$base64url = base64_encode($enurl);
echo $base64url, PHP_EOL;
// aHR0cHMlM0ElMkYlMkZ3d3cuenlibG9nLm5ldCUzRm9wdCUzRGRldiUyNm1haWwlM0R6eWJsb2clNDBuZXQubmV0JTI2Y29tbWVudHMlM0RhYWErYmJiK2NjYyslMjVkZmcrJTI2JTNEJTNEJTJBJTI4JTI5K2NkZyUyNnZhbHVlJTNEJUUyJTgwJTlDJUU0JUI4JUFEJUU2JTk2JTg3JUU0JUI5JTlGJUU2JTlDJTg5JUU1JTkxJTgwJUVGJUJDJThDJUU4JUJGJTk4JUU2JTlDJTg5JUU0JUI4JUFEJUU2JTk2JTg3JUU3JUFDJUE2JUU1JThGJUI3JUVGJUJDJTgxJUVGJUJDJTgxJUUyJTgwJTlE
echo base64_decode($base64url), PHP_EOL;
// https%3A%2F%2Fwww.zyblog.net%3Fopt%3Ddev%26mail%3Dzyblog%40net.net%26comments%3Daaa+bbb+ccc+%25dfg+%26%3D%3D%2A%28%29+cdg%26value%3D%E2%80%9C%E4%B8%AD%E6%96%87%E4%B9%9F%E6%9C%89%E5%91%80%EF%BC%8C%E8%BF%98%E6%9C%89%E4%B8%AD%E6%96%87%E7%AC%A6%E5%8F%B7%EF%BC%81%EF%BC%81%E2%80%9D
其实Base64最大的用处并不体现在对这种普通字符串的编码上,而是体现在编码后传输中二进制字符串的作用。想必用过的同学自然知道。主要针对接口开发,如果我们用Base64对数据进行编码,一是没有加密效果,二是可以增加数据的长度,所以除非有特殊需要,普通传输真的没多少. 有必要对数据进行base64编码。
URL解析操作
除了对URL链接中的字符进行编码和解码之外,解析链接参数也是我们经常使用的一个功能。例如:
$urls = parse_url($url);
var_dump($urls);
// array(3) {
// ["scheme"]=>
// string(5) "https"
// ["host"]=>
// string(14) "www.zyblog.net"
// ["query"]=>
// string(119) "opt=dev&mail=zyblog@net.net&comments=aaa bbb ccc %dfg &==*() cdg&value=“中文也有呀,还有中文符号!!”"
// }
通过 parse_url() 函数,我们可以拆解链接的各个部分。
$parseTestUrl = 'http://username:password@hostname/path?arg=value#anchor';
print_r(parse_url($parseTestUrl));
// Array
// (
// [scheme] => http
// [host] => hostname
// [user] => username
// [pass] => password
// [path] => /path
// [query] => arg=value
// [fragment] => anchor
// )
上面的测试环节比较标准。我们还可以看到 parse_url() 可以拆解协议、地址、用户名、密码、路径、查询语句、分片的内容。这些也是形成 URL 链接的标准标准。我们也可以指定我们需要什么。
echo parse_url($parseTestUrl, PHP_URL_PATH); // /path
通过像这样添加第二个参数,我们只能得到我们需要的一部分。当然,对于整个 URL 链接,我们最关心的还是查询部分的内容。我们可以拆卸它们吗?就像 $_GET 获取所有查询数据结果一样。
$querys = [];
parse_str($urls['query'], $querys);
var_dump($querys);
// array(4) {
// ["opt"]=>
// string(3) "dev"
// ["mail"]=>
// string(14) "zyblog@net.net"
// ["comments"]=>
// string(15) "aaa bbb ccc �g "
// ["value"]=>
// string(48) "“中文也有呀,还有中文符号!!”"
// }
parse_str() 这个函数就是解析这种URL链接查询语句的函数。需要注意的是,这个函数的第二个参数是可选的。如果一个变量不用于接收这个函数解析的结果,那么所有的解析结果将直接转换成变量形式。说起来可能有点晕,直接看代码就行了。
parse_str($urls['query']);
echo $value, PHP_EOL; // “中文也有呀,还有中文符号!!”
现在看看。为了防止变量污染的问题,最好有第二个参数,把解析的结果存放在我们指定的地方。最后,让我们看看如何将数组组合成一个 URL 查询。
echo http_build_query($querys), PHP_EOL;
// opt=dev&mail=zyblog%40net.net&comments=aaa+bbb+ccc+%DFg+&value=%E2%80%9C%E4%B8%AD%E6%96%87%E4%B9%9F%E6%9C%89%E5%91%80%EF%BC%8C%E8%BF%98%E6%9C%89%E4%B8%AD%E6%96%87%E7%AC%A6%E5%8F%B7%EF%BC%81%EF%BC%81%E2%80%9D
echo http_build_query($querys, null, '$||#39;, PHP_QUERY_RFC3986), PHP_EOL;
// opt=dev$||$mail=zyblog%40net.net$||$comments=aaa%20bbb%20ccc%20%DFg%20$||$value=%E2%80%9C%E4%B8%AD%E6%96%87%E4%B9%9F%E6%9C%89%E5%91%80%EF%BC%8C%E8%BF%98%E6%9C%89%E4%B8%AD%E6%96%87%E7%AC%A6%E5%8F%B7%EF%BC%81%EF%BC%81%E2%80%9D
http_build_query() 其实做过外部接口开发的同学都不会陌生。因为太方便了。不过需要注意的是,这个函数会自动使用 rawurlencode() 对数据进行编码。此外,它还有几个可选参数。比如我们修改了第二个测试代码中的连接符号,将原来的&符号替换为我们自定义的符号来拼接URL查询语句。
解析文件或远程地址的响应头和元信息
对于远程文件请求,响应头信息也很重要。其实在URL相关的组件中也有直接获取响应头的功能。
$url = 'https://www.sina.com.cn';
print_r(get_headers($url));
// Array
// (
// [0] => HTTP/1.1 200 OK
// [1] => Server: nginx
// [2] => Date: Mon, 25 Jan 2021 02:08:35 GMT
// [3] => Content-Type: text/html
// [4] => Content-Length: 530418
// [5] => Connection: close
// [6] => Vary: Accept-Encoding
// [7] => ETag: "600e278a-7c65e"V=5965C31
// [8] => X-Powered-By: shci_v1.13
// [9] => Expires: Mon, 25 Jan 2021 02:09:12 GMT
// [10] => Cache-Control: max-age=60
// [11] => X-Via-SSL: ssl.22.sinag1.qxg.lb.sinanode.com
// [12] => Edge-Copy-Time: 1611540513080
// [13] => Age: 24
// [14] => Via: https/1.1 cmcc.guangzhou.union.82 (ApacheTrafficServer/6.2.1 [cRs f ]), https/1.1 cmcc.jiangxi.union.175 (ApacheTrafficServer/6.2.1 [cRs f ])
// [15] => X-Via-Edge: 1611540515462770a166fee55a97524d289c7
// [16] => X-Cache: HIT.175
// [17] => X-Via-CDN: f=edge,s=cmcc.jiangxi.union.166.nb.sinaedge.com,c=111.22.10.119;f=edge,s=cmcc.jiangxi.union.168.nb.sinaedge.com,c=117.169.85.166;f=Edge,s=cmcc.jiangxi.union.175,c=117.169.85.168
// )
print_r(get_headers($url, 1));
// Array
// (
// [0] => HTTP/1.1 200 OK
// [Server] => nginx
// [Date] => Mon, 25 Jan 2021 02:08:35 GMT
// [Content-Type] => text/html
// [Content-Length] => 530418
// [Connection] => close
// [Vary] => Accept-Encoding
// [ETag] => "600e278a-7c65e"V=5965C31
// [X-Powered-By] => shci_v1.13
// [Expires] => Mon, 25 Jan 2021 02:09:12 GMT
// [Cache-Control] => max-age=60
// [X-Via-SSL] => ssl.22.sinag1.qxg.lb.sinanode.com
// [Edge-Copy-Time] => 1611540513080
// [Age] => 24
// [Via] => https/1.1 cmcc.guangzhou.union.82 (ApacheTrafficServer/6.2.1 [cRs f ]), https/1.1 cmcc.jiangxi.union.175 (ApacheTrafficServer/6.2.1 [cRs f ])
// [X-Via-Edge] => 1611540515593770a166fee55a97568f1a9d6
// [X-Cache] => HIT.175
// [X-Via-CDN] => f=edge,s=cmcc.jiangxi.union.165.nb.sinaedge.com,c=111.22.10.119;f=edge,s=cmcc.jiangxi.union.175.nb.sinaedge.com,c=117.169.85.165;f=Edge,s=cmcc.jiangxi.union.175,c=117.169.85.175
// )
目标地址服务器返回的响应头信息可以直接通过get_headers()函数获取。它的第二个参数可以以键值下标的形式返回数据。除了响应头,我们还可以获得网站的所有meta标签的内容。
var_dump(get_meta_tags($url));
// array(11) {
// ["keywords"]=>
// string(65) "新浪,新浪网,SINA,sina,sina.com.cn,新浪首页,门户,资讯"
// ["description"]=>
// string(331) "新浪网为全球用户24小时提供全面及时的中文资讯,内容覆盖*敏*感*词*突发新闻事件、体坛赛事、娱乐时尚、产业资讯、实用信息等,设有新闻、体育、娱乐、财经、科技、房产、汽车等30多个内容频道,同时开设博客、视频、论坛等自由互动交流空间。"
// ["referrer"]=>
// string(6) "always"
// ["stencil"]=>
// string(10) "PGLS000022"
// ["publishid"]=>
// string(8) "30,131,1"
// ["verify-v1"]=>
// string(44) "6HtwmypggdgP1NLw7NOuQBI2TW8+CfkYCoyeB8IDbn8="
// ["application-name"]=>
// string(12) "新浪首页"
// ["msapplication-tileimage"]=>
// string(42) "//i1.sinaimg.cn/dy/deco/2013/0312/logo.png"
// ["msapplication-tilecolor"]=>
// string(7) "#ffbf27"
// ["baidu_ssp_verify"]=>
// string(32) "c0e9f36397049594fb9ac93a6316c65b"
// ["sudameta"]=>
// string(20) "dataid:wpcomos:96318"
// }
该功能不仅对远程链接网站有用,还可以直接查看本地静态文件中所有meta标签的内容,我们只需要将参数的远程链接替换为本地文件的路径即可. ,你可以自己试试。
总结
今天的内容比较简单,主要是日常工作中经常用到的这些功能。不过有些参数的用法可能很多朋友都不清楚,比如parse_str()函数的第二个参数的问题。所以就像我一开始说的,这个文章是一个回顾和巩固,也起到加深理解的作用。经过深入研究,结合实际应用,会更容易掌握。
测试代码:
学习PHP.php中URL相关的操作函数
参考文档: