最近有一个任务,从页面中抓取页面中所有的链接,当然使用PHP正则表达式是最方便的办法。要写出正则表达式,就要先总结出模式,那么页面中的链接会有几种形式呢?
 
链接也就是超级链接,是从一个元素(文字、图片、视频等)链接到另一个元素(文字、图片、视频等)。网页中的链接一般有三种,一种是绝对URL超链接,也就是一个页面的完整路径;另一种是相对URL超链接,一般都链接到同一网站的其他页面;还有一种是页面内的超链接,这种一般链接到同一页面内的其他位置。
 
搞清楚了链接的种类,就知道要抓链接,主要还是绝对URL超链接和相对URL超链接。要写出正确的正则表达式,就必须要了解我们查找的对象的模式。
 
先说绝对链接,也叫作URL(Uniform Resource Locator),标识了互联网上的唯一资源。URL的结构包含三部分:协议、服务器名称、路径和文件名。
 
协议是告诉浏览器如何处理将要打开文件的标识,最常见的就是 http 协议。本文也只考虑HTTP协议,至于其他的 https、ftp、mailto、telnet协议等,根据需要也可以添加。
 
服务器名称是告诉浏览器如何到达这个服务器的方式,通常是域名或者IP地址,有时还会包含端口号(默认为80)。FTP协议中,也可以包含用户名和密码,本文就不考虑了。
 
路径和文件名,一般以 / 分割,指出到达这个文件的路径和文件本身的名称。如果没有具体的文件名,则访问这个文件夹下的默认文件(可以在服务器端设置)。
 
那么现在清楚了,要抓取的绝对链接的典型形式可以概括为 
 
http://www.xxx.com/xxx/yyy/zzz.html
 
每个部分可以使用的字符范围有明确的规范,具体可以参考RFC1738。那么正则表达式就可以写出来了。
 
/(http|https):\/\/([\w\d\-_]+[\.\w\d\-_]+)[:\d+]?([\/]?[\w\/\.]+)/i
 
解释如下:
 
(http|https)第一个括号内匹配的是协议部分。
 
([\w\d\-_]+[\.\w\d\-_]+)第二个括号内匹配的是域名部分。
 
([\/]?[\w\/\.]+)第三个括号内匹配的是相对路径。
 
写到这个时候,基本上大部分的网址都能匹配到了,但是对于URL中带有参数的还不能抓取,这样有可能造成再次访问的时候页面报错。关于参数RFC1738规范中要求是用?来分割,后面带上参数,但是现代的RIA应用有可能使用其他奇怪的形式进行分割。
 
稍微修改一下,这样就可以将查询参数部分搜索出来。这里仍然没有涵盖全部的情况,例如URL中有中文、有空格及其他特殊字符的情况,但是基本上能够满足我的需求了,就没有继续深化。
 
/(http|ftp|https):\/\/([\w\d\-_]+[\.\w\d\-_]+)[:\d+]?([\/]?[\w\/\.\?=&;%@#\+,]+)/i
 

使用括号的好处是,在处理结果时,可以很容易的获取到协议、域名、相对路径这些内容,方便后续的处理。
 
例如使用 preg_match_all() 匹配时,结果数组索引0为全部结果、1为协议、2为域名、3为相对路径。
 

参考资料:

使用PHP的正则抓取页面中的网址的更多相关文章

  1. Python抓取页面中超链接(URL)的三中方法比较(HTMLParser、pyquery、正则表达式) <转>

    Python抓取页面中超链接(URL)的3中方法比较(HTMLParser.pyquery.正则表达式) HTMLParser版: #!/usr/bin/python # -*- coding: UT ...

  2. 点滴积累【C#】---抓取页面中想要的数据

    效果: 描述:此功能是抓取外国的一个检测PM2.5的网站.实时读取网站的数据,然后保存到数据库里面.每隔一小时刷新一次. 地址为:http://beijing.usembassy-china.org. ...

  3. 通过CURL抓取页面中的图片路径并下载到本地

    1.首页是图片处理页面downpic.php <?phpfunction getImage($url,$filename="") { if($url=="" ...

  4. PHP抓取页面中的邮箱

    <?php $url='http://www.cnblogs.com/tinyphp/p/3234926.html'; //当页已留邮箱 $content=file_get_contents($ ...

  5. 浅谈如何使用python抓取网页中的动态数据

    我们经常会发现网页中的许多数据并不是写死在HTML中的,而是通过js动态载入的.所以也就引出了什么是动态数据的概念, 动态数据在这里指的是网页中由Javascript动态生成的页面内容,是在页面加载到 ...

  6. 用正则表达式抓取网页中的ul 和 li标签中最终的值!

                获取你要抓取的页面 const string URL = "http://www.hn3ddf.gov.cn/price/GetList.html?pageno=1& ...

  7. java中使用 正则 抓取邮箱

    我们来抓取豆瓣网的邮箱吧!把这个页面的所有邮箱都抓取下来 如https://www.douban.com/group/topic/8845032/: 代码如下: package cn.zhangzon ...

  8. 用PHP抓取页面并分析

    在做抓取前,记得把php.ini中的max_execution_time设置的大点,不然会报错的.

  9. curl抓取页面时遇到重定向的解决方法

    用php的curl抓取网页遇到了问题,为阐述方便,将代码简化如下: <?php function curlGet($url) { $ch = curl_init(); curl_setopt($ ...

随机推荐

  1. GPS部标平台的架构设计(五)-地图服务算法库

    GPS平台,需要和各种地图打交道,需要解决以下的问题: 1.坐标偏移,这个不用多说,需要将原始坐标加偏,然后在百度地图或谷歌上显示出来,需要注意的是百度地图的加偏是偏上再偏,谷歌.高德地图等是火星坐标 ...

  2. python中的GIL(全局解释锁)多线程能够提升效率

    预启动的时候,应用程序仍然会调用 OnLaunched 方法的,在 OnLaunched 方法调用之后,会马上发生 Suspending 事件,随后应用就会暂停. 我先基于develop主分支拉出一个 ...

  3. Jquery 定时器 倒计时

    <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8&qu ...

  4. C# 控件的自定义拖动、改变大小方法

    在用VS的窗体设计器时,我们可以发现控件都是可以拖动的,并且还可以调整大小.怎么在自己的程序中可以使用上述功能呢? 下面的方法值得借鉴! using System; using System.Wind ...

  5. JAVA-JNI java程序调用c/c++程序

    目的:写c/c++函数,让java调用 java代码 1.创建HelloJNI.java文件->编写代码如下->cmd中javac HelloJNI.java获取HelloJNI.clas ...

  6. 搭建git for windows服务器

    文档出处 :http://blog.csdn.net/code_style/article/details/38764203 http://blog.csdn.net/aaron_luchen/art ...

  7. paper 114:Mahalanobis Distance(马氏距离)

    (from:http://en.wikipedia.org/wiki/Mahalanobis_distance) Mahalanobis distance In statistics, Mahalan ...

  8. 敏捷项目开源管理软件ScrumBasic(2)- 多项目支持

    1.加入Project对象模型 public class Project { [Key] [MaxLength(32)] public string ID { get; set; } public s ...

  9. .net之工作流工程展示及代码分享(预告)

    最近在帮公司做一个工作流程序模块,要求是可以嵌入到各种现有的程序中去.我想把自己制作的思路和过程同大家分享. 先上一张结构图: 由于该项目我一个人做,所以系统结构不能太复杂. 用到的技术主要有:DDD ...

  10. JS SDK 随手笔记

    JS SDK 随手笔记 窗口模块 Frame/Multi Frame 对话框 页面间的通讯 生命周期 窗口层叠 窗口模块 窗口模块是是AppCan移动应用界面最基本的单位.窗口是每个界面布局的基础,他 ...