文章目录
- 1网络爬虫
- 2网络爬虫的类型
- 2.1通用网络爬虫
- 2.1.1
- 2.1.2
- 2.2聚焦网络爬虫
- 2.2.1 基于内容评价的爬行策略
- 2.2.2 基于链接结构的爬行策略
- 2.2.3基于增强学习的爬行策略
- 2.2.4基于语境图的爬行策略
- 2.3增量式网络爬虫
- 深层网页爬虫
- 3网络爬虫基本架构
- 3.1URL管理模块
- 3.2网页下载模块
- 3.3网页解析模块
- 3.4数据存储器
- 4网页下载模块
- 4.1 requests简介
- 4.2 requests库的使用
- 5网页解析模块
- 5.1 beautiful soup4简介
- 5.2 创建beautiful soup4 对象
- 5.3 查询结点
- 5.4获取结点信息
- 5.4.1利用Tag对象获取结点信息
- 5.4.2利用BeautifulSoup对象获取其他结点信息
- 6 案例
1网络爬虫
网络爬虫(web spider)又称网络机器人、网络蜘蛛,是一种根据既定规则,自动提取网页信息的程序或脚本。将互联网上的目标网页数据保存到本地,以便进行本地数据文件操作和后续处理
传统爬虫以一个或若干初始网页的统一资源定位符(Uniform Resource Location ,URL)为起点,下载每一个URL指定的网页,分析并获取页面内容,并不断从当前页面抽取新的URL放入队列,记录每一个已经爬取过的页面,直到URL队列为空或满足设定的停止条件为止。
2网络爬虫的类型
2.1通用网络爬虫
通用网络爬虫又称全网爬虫,爬行对象从一些种子URL扩充到整个Web ,主要为门户站点搜索引擎和大型Web服务提供商采集数据。这类网络爬虫的爬行范围和数量巨大,对爬行速度和存储空间要求较高,而对爬行页面的顺序要求相对较低,通常采用并行工作方式应对大量待刷新的页面,适合为搜索引擎获取广泛的主题。
通用网络爬虫大致由页面爬行模块、页面分析模块、链接过滤模块、页面数据库、URL队列和初始URL集合等几部分构成。为了提高工作效率,通用网络爬虫可以采用深度优先和广度优先等爬行策略。
2.1.1
采用深度优先爬行策略的爬虫按照深度由低到高的顺序,依次访问下一级网页链接,直到不能再深入为止。爬虫在完成一个爬行分支后返回上一个链接节点进一步搜索其它链接。当所有链接遍历完毕,爬行任务结束。这种爬行策略比较适合垂直搜索或站内搜索,但爬行页面内容层次较深的站点时会造成资源的巨大浪费。
2.1.2
采用广度优先爬行策略的爬虫按照网页内容目录层次深浅来爬行页面,优先爬取目录层次较浅的页面。当同一层次的页面爬行完毕,再深入下一层次继续爬取。这种爬行策略能够有效控制页面的爬取深度,避免遇到一个无穷深层分支时无法结束爬行的问题。该策略无需存储大量的中间节点,不足之处是需要较长时间才能爬行到目录层次较深的页面。
2.2聚焦网络爬虫
聚焦网络爬虫又称主题网络爬虫,它会选择性地爬取与预定主题相关的页面。与通用网络爬虫相比,聚焦网络爬虫只需爬取与主题相关的页面,极大地节省了硬件和网络资源,保存页面数量少且更新快,可以更好地满足特定人群对特定领域信息的爬取需求。页面内容和链接重要性不同导致链接的访问顺序也不一样,聚焦爬虫爬行策略因此分为以下四种。
2.2.1 基于内容评价的爬行策略
基于内容评价的爬行策略将文本相似度计算方法引入网络爬虫中。该策略以用户输入的查询词为主题,将包含查询词的页面视为主题相关页面,其局限性在于无法评价页面与主题相关度的高低,可以尝试利用空间向量模型计算页面与主题的相关度大小。
2.2.2 基于链接结构的爬行策略
网页页面中的链接指示了页面之间的相互关系,基于链接结构的搜索策略模式利用这些结构特征评价页面和链接的重要性,以此决定搜索顺序。其中,PageRank算法是这类搜索策略的代表,具体做法是每次选择PageRank值较大的页面链接进行访问。
2.2.3基于增强学习的爬行策略
基于增强学习的爬行策略将增强学习引入聚焦爬虫,利用贝叶斯分类器,根据整个网页文本和链接文本对超链接进行分类,为每个链接计算出重要性,从而决定链接的访问顺序。
2.2.4基于语境图的爬行策略
基于语境图的爬行策略通过建立语境图来学习网页之间的相关度。该策略训练一个机器学习系统,通过该系统计算当前页面到相关Web页面的距离,距离近的页面中的链接优先访问。
2.3增量式网络爬虫
增量式网络爬虫**对已下载的网页采取增量式更新策略,只爬行新产生或已经发生变化的网页,在一定程度上保证爬行尽可能新的页面。**与周期性爬行和刷新页面的爬虫相比,增量式爬行按需爬取新产生或发生更新的页面内容,有效减少了数据下载量并及时更新爬行过的网页,减小时间和空间上的耗费,但是增加了爬行算法的复杂度和实现难度。
为了保持本地存储的页面为最新页面,增量式爬虫通过监测网页数据的更新情况,持续更新本地的页面内容,常用方法有:
统一更新法︰爬虫以相同的频率访问所有网页,不考虑网页的改变频率。
个体更新法︰爬虫根据个体网页的改变频率重新访问各页面。
基于分类的更新法︰爬虫根据网页改变频率分为更新较快网页子集和更新较慢网页子集两类,然后以不同的频率访问这两类网页。
为了保证本地集中的页面质量,增量式爬虫需要对网页的重要性进行排序,常用广度优先策略和PageRank优先策略;也可以采用自适应方法,根据历史爬取结果和网页实际变化速度对页面更新频率进行调整;或者将网页分为变化网页和新网页两类,分别采用不同的爬行策略。
深层网页爬虫
Web页面按照存在方式可以分为表层网页和深层网页两类。表层网页是指传统搜索引擎可以索引到的页面,以超链接可以到达的静态网页为主。深层网页是指隐藏在搜索表单后,大部分内容不能通过静态链接获取,只有用户提交关键词才能获得的Web页面。深层网页是目前互联网上最大、发展最快的新型信息资源。深层网页爬虫爬行过程中最重要的部分就是表单填写,表单填写方法可以分为两类。
基于领域知识的表单填写∶此方法一般会维持一个本体库,通过语义分析来选取合适的关键词填写表单。一种方法是将数据表单按照语义分配到各个组中,每组从多方面注解,结合各种注解结果预测最终的注解标签;也可以利用一个预定义的领域本体知识库来识别深层网页内容,同时利用Web站点导航模式识别自动填写表单时所需的路径导航。
基于网页结构分析的表单填写:此方法一般无需领域知识或仅利用有限领域知识,将网页表单表示为文档对象模型(Document Object Model ,DOM),从中提取表单各字段值。一种方法是将HTML网页表示为DOM树形式,将表单区分为单属性表单和多属性表单,分别进行处理;也可以将Web文档构造成DOM树,将文字属性映射到表单字段。
3网络爬虫基本架构
3.1URL管理模块
URL管理模块负责管理URL链接,维护已经爬行的URL集合和计划爬行的URL集合,防止重复爬取或循环爬取。其主要功能包括︰添加新的URL链接、管理已爬行的URL和未爬行的URL以及获取待爬行的URL。
URL管理模块的实现方式有两种:一种是利用python中集合数据类型不包含重复元素的特点达到去重效果,防止重复爬取或循环爬取;另一种实现方式是在数据库表中创建记录时,为每一个URL增加一个标志字段,例如︰已爬行的网页链接标记为“1”,未爬行的网页链接标记为“O”。当有新链接产生时,先在已爬行的链接集中查询,如果发现该链接已被标记为“1”,那么不再爬行该URL的链接页面。
3.2网页下载模块
这是网络爬虫的核心组件之一,用于从URL管理模块中将指定URL对应的页面下载到本地或者以字符串形式读入内存,方便后续使用字符串相关操作解析网页内容。
Python第三方库requests是一个处理HTTP请求的模块,其最大优点是程序编写过程更接近正常的URL访问过程。
3.3网页解析模块
网页解析模块是网络爬虫的另一个核心组件,用于从网页下载模块获取已下载的网页,并解析出有效数据交给数据存储器。网页解析的实现方式多种多样。由于下载到本地的网页内容以字符串形式保存,可以使用字符串相关操作从中解析出有价值的结构数据,例如:可以使用正则表达式指定规则,然后根据规则找出感兴趣的字符串;也可以使用python自带的HTML解析工具html.parser从网页内容的字符串中解析出相关信息;还可以使用python第三方库beautifulsoup4实现网页解析。作为一种功能强大的结构化网页解析工具,beautifulsoup4模块能够根据HTML和XML语法建立解析树,进而高效解析和处理页面内容。
3.4数据存储器
数据存储器负责将网页解析模块解析出的数据存储起来,用于后续的数据分析和信息利用。
4网页下载模块
4.1 requests简介
requests是python中一个处理HTTP请求的第三方库,需要预先安装。requests模块在python内置模块的基础上进行了高度封装,使得python进行网络请求时更加简洁和人性化。
requests库支持非常丰富的链接访问功能,包括HTTP长连接和连接缓存、国际域名和URL获取、HTTP会话和Cookie保持、浏览器使用风格的SSL验证、自动内容解码、基本摘要身份验证、有效键值对的Cookie记录、自动解压缩、Unicode响应主体、HTTP ( S )代理支持、文件分块上传、流式下载、连接超时和分块请求等。
4.2 requests库的使用
通过URL访问网络链接并返回网页内容是requests模块的基本功能,其中与网页请求相关的函数有6个,具体使用方法如表所示。
# requests.get()方法向目标网址发送请求,接收响应,该方法返回一个response对象。这里的参数url必须采用HTTP或HTTPS方式访问
In[ ] : import requests
url= 'https: / / www.baidu.com/'
r_obj =requests.get(ur1)
type(r_obj)
out[ ] :requests.models. Response
与浏览器的交互过程类似,调用requests.get()方法后,返回的网页内容保存为一个response对象,便于后续操作。response对象的常用属性如表所示。
import requests
def getHTMLText(url):
try:
r_obj=requests.get(url,timeout=30)
r_obj.raise_for_status()
r_obj.encoding='utf-8'
return r_obj.text
except:
return ""
url="http://www.baidu.com"
print(getHTMLText(url))
5网页解析模块
5.1 beautiful soup4简介
Python第三方库beautifulsoup4(也称BeautifulSoup或bs4库)用于解析和处理HTML、XML文件并提取数据。
beautifulsoup4支持多种解析器,其优势是能够根据HTML和XML语法建立解析树,进而高效解析其中的内容,为用户提供需要的数据。
HTML建立的web页面一般比较复杂,除了有用内容之外,还包含大量用于页面格式的元素。一个网页文件通常可以表示为一个文档对象模型(DOM)。DOM是一种处理HTML和XML文件的标准编程接口,它提供了对整个文档的访问模型,将网页文档表示为一个树形结构,树的每个节点表示一个HTML标签( Tag )或标签内的文本项。
5.2 创建beautiful soup4 对象
# 实例化的Beautifulsoup对象相当于一个页面,表示一个文档的全部内容
In[ ] : import requests
From bs4 import BeautifulSoupurl = 'http://www.baidu.com'r_obj = requests.get(url)
bs = BeautifulSoup(r_obj.content, from_encoding='utf-8')
type(bs)
out[ ] : bs4.BeautifulSoup
BeautifulSoup对象是一个树状结构,它包含了HTML页面的每一个标签(Tag )元素,如、等。也就是说,HTML的主要结构都成为BeautifulSoup对象的属性。表中列出了BeautifulSoup对象的常用属性。
5.3 查询结点
- find() 方法
- find()方法实现指定范围内的单次条件定位,目的是找到满足条件的第一个节点,返回第一个匹配到的对象。格式如下:
find(name, attrs, recursive, string)
- 参数name:标签名,可以是字符串类型,定位到指定标签名的结点;也可以是列表类型,用于匹配多个标签名;还可以是正则表达式,用于传递自定义的标签名规则;找到后返回一个BeautifulSoup标签对象。
- 参数attrs:标签的属性,以字典类型指定标签的属性名及属性值,查找其第一次出现的位置,找到后返回一个BeautifulSoup标签对象;
- 参数recursive: 设置查找层次,参数为布尔类型数据,默认为True,表示当前标签下的所有子孙标签;如果设置为False,表示只查找当前标签下的直接子标签;
- 参数text:查找标签的文本内容,而不使用标签的属性去匹配。参数可以是字符串类型,字符串列表等,搜索指定范围的字符串内容,返回匹配字符串的列表。
- findall() 方法
- find_all()方法实现指定范围内多个符合要求的定位,目的是找到所有满足条件的节点,返回多个匹配结果构成的列表。find_all)方法语法格式如下∶
find_all(name, attrs, recursive, text, limit,**kwargs)
- 其中范围限制参数limit只用于find_all()方法,用于设置网页中获取结果的范围。find()方法等价于参数limit等于1的情形。参数**kwargs用于选择具有指定属性的标签,属于冗余技术。其它参数的含义与find)方法类似。
# 查找title标签
bs.find('title')
# 查找第一个链接标签
bs.find('a')
# 查找所有的链接标签
bs.find_all('a')
# 查找class为mnav的所有链接标签
bs.find_all('a', class_='mnav')
5.4获取结点信息
5.4.1利用Tag对象获取结点信息
不难发现,BeautifulSoup对象的属性名与HTML的标签名称相同。实际上,HTML页面中的每一个Tag元素在beautifulsoup4库中也是一个对象,称为Tag对象,如、
import requests
import lxml
from bs4 import BeautifulSoup
url = 'http://www.baidu.com'
r_obj = requests.get(url)
bs = BeautifulSoup(r_obj.content, 'lxml',from_encoding='utf-8')
# 查找第一个链接标签
link_tag = bs.find('a')
# 节点标签名称
link_tag.name
# 节点的属性
link_tag.attrs
link_tag['href']
link_tag.text
5.4.2利用BeautifulSoup对象获取其他结点信息
一个网页文件通常表示为一个DOM树结构,它精确地描述了HTML文档中标签结点间的层次关系。在解析网页文档的过程中,可以利用beautifulsoup4模块中BeautifulSoup对象的上行遍历属性和下行遍历属性获取不同层次结点的信息。
url = 'http://www.pythonscraping.com/pages/page3.html'
r_obj = requests.get(url)
bs_obj = BeautifulSoup(r_obj.content, 'lxml')
# 获取表格标签
table_tag = bs_obj.find('table')
# 获取表格的每行内容,即“孩子”结点
for row in table_tag.children:
print(row)
# 获取子孙结点
for descendant in table_tag.descendants:
print(descendant)
# 返回下一个“同辈”结点
first_row = table_tag.find('tr')
for sibling in first_row.next_siblings:
print(sibling)
# 返回“父亲”结点
first_row.parent
6 案例
import requests
from bs4 import BeautifulSoup
# 爬取红楼梦全集并存盘
if __name__ == '__main__':
# 目录页
url = 'http://hongloumeng.5000yan.com/'
req = requests.get(url)
# 解析目录页
soup = BeautifulSoup(req.content, from_encoding='utf-8')
# find_next找到第二个div
soup_text = soup.find('div', class_='sidamingzhu-list-mulu')
# 遍历ul的子结点,获得标题和对应的链接地址
f = open('hongloumeng.txt', 'w', encoding='utf-8')
for link in soup_text.ul.children:
if link != '\n':
download_url = link.a.get('href')
download_req = requests.get(download_url)
download_soup = BeautifulSoup(download_req.content, from_encoding='utf-8')
download_text = download_soup.find('div', class_='grap')
f.write(f'\n{link}\n')
f.write(download_text.text)
f.close()