300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > Python爬虫编程思想(6):实战案例:抓取所有的网络资源

Python爬虫编程思想(6):实战案例:抓取所有的网络资源

时间:2018-09-03 16:25:45

相关推荐

Python爬虫编程思想(6):实战案例:抓取所有的网络资源

Python爬虫编程思想(7):实战案例:抓取博客文章列表

到现在为止,我们已经对网络爬虫涉及到的基本知识有了一个初步的了解。本文会编写一个简单的爬虫应用,以便让读者对爬虫有一个基本的认识。本节要编写的爬虫属于全网爬虫类别,但我们肯定不会抓取整个互联网的资源。所以本节会使用7个HTML文件来模拟互联网资源,并将这7个HTML文件放在本地的nginx服务器的虚拟目录,以便抓取这7个HTML文件。

全网爬虫要至少有一个入口点(一般是门户网站的首页),然后会用爬虫抓取这个入口点指向的页面,接下来会将该页面中所有链接节点(a节点)中href属性的值提取出来。这样会得到更多的Url,然后再用同样的方式抓取这些Url指向的HTML页面,再提取出这些HTML页面中a节点的href属性的值,然后再继续,直到所有的HTML页面都被分析完为止。只要任何一个HTML页面都是通过入口点可达的,使用这种方式就可以抓取所有的HTML页面。这很明显是一个递归过程,下面就用伪代码来描述这一递归过程。

从前面的描述可知,要实现一个全网爬虫,需要下面两个核心技术。

下载Web资源(html、css、js、json)分析Web资源

假设下载资源通过download(url)函数完成,url是要下载的资源链接。download函数返回了网络资源的文本内容。analyse(html)函数用于分析Web资源,html是download函数的返回值,也就是下载的HTML代码。analyse函数返回一个列表类型的值,该返回值包含了HTML页面中所有的URL(a节点href属性值)。如果HTML代码中没有a节点,那么analyse函数返回空列表(长度为0的列表)。下面的drawler函数就是下载和分析HTML页面文件的函数,外部程序第1次调用crawler函数时传入的URL就是入口点HTML页面的链接。

def crawler(url){# 下载url指向的HTML页面html = download(url)# 分析HTML页面代码,并返回该代码中所有的URLurls = analyse(html)# 对URL列表进行迭代,对所有的URL递归调用crawler函数for url in urls{crawler(url)}}# 外部程序第一次调用crawler函数,http://localhost/files/index.html就是入口点的URLcrawler('http://localhost/files/index.html ')

本节的例子需要使用到nginx服务器,下面是nginx服务器的安装方法。

nginx是免费开源的,下载地址是/en/download.html。如果读者使用的是Windows平台,直接下载nginx压缩包(一个zip压缩文件),直接解压即可。如果读者使用的是Mac OS X或Linux平台,需要使用下面的方式编译nginx源代码,并安装nginx。

进入nginx源代码目录,然后执行下的命令配置nginx。

./configure --prefix=/usr/local/nginx

上面的配置指定了nginx的安装目录是/usr/local/nginx。

接下来执行下面的命令编译和安装nginx。

make && make install

如果安装成功,会在/usr/local目录下看到nginx目录。

下面会使用递归的方式编写了一个全网爬虫,该爬虫会从本地的nginx服务器(其他Web服务器也可以)抓取所有的HTML页面,并通过正则表达式分析HTML页面,提取出a节点的href属性值,最后将获得的所有URL输出到Console。

在编写代码之前,先要准备一个Web服务器(Nginx、Apache、IIS都可以),并建立一个虚拟目录。Nginx默认的虚拟目录路径是根目录>/html。然后准备7个HTML文件,这些HTML文件的名称和关系如图1所示。

很明显,index.html文件是入口点,从index.html文件可以导向a.html、b.html和c.html。从a.html可以导向aa.html和bb.html,从c.html可以导向cc.html。也就是说,只要从index.html文件开始抓取,就可以成功抓取所有的HTML文件。

现在将这7个HTML文件都放在根目录>/html/files目录下,然后按下面的代码编写爬虫程序。

7个HTML文件所在的目录位置是src/firstspider/files

下面是本例的7个HTML文件的代码,爬虫会抓取和分析这7个HTML文件的代码。

<!-- index.html 入口点 --><html><head><title>index.html</title></head><body><a href='a.html'>first page</a><p><a href='b.html'>second page</a><p><a href='c.html'>third page</a><p></body></html><!-- a.html --><html><head><title>a.html</title></head><body><a href='aa.html'>aa page</a><p><a href='bb.html'>bb page</a></body></html><!-- b.html --><html><head><title>b.html</title></head><body>b.html</body></html><!-- c.html --><html><head><title>c.html</title></head><body><a href='cc.html'>cc page</a></body></html><!-- aa.html --><html><head><title>aa.html</title></head><body>aa.html</body></html><!-- bb.html --><html><head><title>bb.html</title></head><body>bb.html</body></html><!-- cc.html --><html><head><title>cc.html</title></head><body>cc.html</body></html>

从上面的代码可以看到,b.html、aa.html、bb.html和cc.html文件中并没有a节点,所以这4个HTML文件是递归的终止条件。

下面是基于递归算法的爬虫的代码。

from urllib3 import *from re import *http = PoolManager()disable_warnings()# 下载HTML文件def download(url):result = http.request('GET', url)# 将下载的HTML文件代码用utf-8格式解码成字符串htmlStr = result.data.decode('utf-8')# 输出当前抓取的HTML代码print(htmlStr)return htmlStr# 分析HTML代码def analyse(htmlStr):# 利用正则表达式获取所有的a节点,如<a href='a.html'>a</a>aList = findall('<a[^>]*>',htmlStr)result = []# 对a节点列表进行迭代for a in aList:# 利用正则表达式从a节点中提取出href属性的值,如<a href='a.html'>中的a.htmlg = search('href[\s]*=[\s]*[\'"]([^>\'""]*)[\'"]',a)if g != None:# 获取a节点href属性的值,href属性值就是第1个分组的值url = g.group(1)# 将Url变成绝对链接 url = 'http://localhost/files/' + url# 将提取出的Url追加到result列表中result.append(url)return result# 用于从入口点抓取HTML文件的函数def crawler(url):# 输出正在抓取的Urlprint(url)# 下载HTML文件 html = download(url)# 分析HTML代码urls = analyse(html)# 对每一个Url递归调用crawler函数for url in urls:crawler(url)# 从入口点Url开始抓取所有的HTML文件crawler('http://localhost/files')

在运行程序之前,要先启动nginx服务,启动方式如下:

Windows:双击nginx.exe文件。macOS和Linux:在终端进入nginx根目录,执行sudo sbin/nginx命令。

程序运行结果如图2所示。

Python爬虫编程思想(7):实战案例:抓取博客文章列表

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。