php抓取网页匹配url(区分和搞清楚每个函数真正的用处-乐题库)

优采云 发布时间: 2022-02-10 13:00

  php抓取网页匹配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相关的操作函数

  参考文档:

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线