网页数据抓取怎么写( 从互联网上爬取语料的经验:0各模块的功能)
优采云 发布时间: 2021-09-16 20:15网页数据抓取怎么写(
从互联网上爬取语料的经验:0各模块的功能)
使用Python3教您任何HTML主内容提取函数
更新时间:2018年11月5日14:14:41作者:腾讯deepcocean
本文文章主要介绍如何使用Python3教您任何HTML主内容提取函数。它主要使用请求、lxml、JSON等模块。本文将逐一介绍这些模块。有需要的朋友可以向他们推荐
本文将与大家分享一些从互联网上抓取语料库的经验
0x1*敏*感*词*准备
如果你想做得好,你必须先磨快你的工具。基于Python
的爬网语料库的建立
我们基于Python3开发,主要使用以下模块:请求、lxml和JSON
简要介绍各模块的功能
01|请求
Requests是一个python第三方库,特别便于处理URL资源。它的官方文件有一个很大的口号:人类的http。与Python自己的urllib体验相比,作者认为请求的使用体验比urllib高一个数量级
让我们做一个简单的比较:
urllib:
import urllib2
import urllib
URL_GET = "https://api.douban.com/v2/event/list"
#构建请求参数
params = urllib.urlencode({'loc':'108288','day_type':'weekend','type':'exhibition'})
#发送请求
response = urllib2.urlopen('?'.join([URL_GET,'%s'])%params)
#Response Headers
print(response.info())
#Response Code
print(response.getcode())
#Response Body
print(response.read())
要求:
import requests
URL_GET = "https://api.douban.com/v2/event/list"
#构建请求参数
params = {'loc':'108288','day_type':'weekend','type':'exhibition'}
#发送请求
response = requests.get(URL_GET,params=params)
#Response Headers
print(response.headers)
#Response Code
print(response.status_code)
#Response Body
print(response.text)
我们可以发现这两个库之间存在一些差异:
1.parameter构造:urllib需要用URLEncode对参数进行编码,比较麻烦;请求非常简洁,无需额外的编码处理
2.request sending:urllib需要构造额外的URL参数才能成为合格的表单;请求更加简洁,直接获得相应的链接和参数
3.connection method:查看返回的头信息的“连接”。使用urlib库时,“连接”:“关闭”表示套接字通道在每个请求结束时关闭,而使用请求库时使用urlib3。多个请求重用套接字“连接”:“保持活动”,表示多个请求使用一个连接,消耗更少的资源
4.encoding method:接受编码在请求库中更完整。这里没有给出例子
综上所述,使用请求更简洁易懂,这对我们的开发非常方便
02÷lxml
Beauty soup是一个库,而XPath是一种技术。Python中最常用的XPath库是lxml
当我们获得请求返回的页面时,我们如何获得所需的数据?目前,lxml是一个强大的HTML/XML解析工具。Python从不缺少解析库,那么为什么我们要在众多库中选择lxml呢?我们选择另一个著名的HTML解析库BeautifulSoup进行比较
让我们做一个简单的比较:
美丽小组:
from bs4 import BeautifulSoup #导入库
# 假设html是需要被解析的html
#将html传入BeautifulSoup 的构造方法,得到一个文档的对象
soup = BeautifulSoup(html,'html.parser',from_encoding='utf-8')
#查找所有的h4标签
links = soup.find_all("h4")
lxml:
from lxml import etree
# 假设html是需要被解析的html
#将html传入etree 的构造方法,得到一个文档的对象
root = etree.HTML(html)
#查找所有的h4标签
links = root.xpath("//h4")
我们可以发现这两个库之间存在一些差异:
1.parsing HTML:Beauty soup的解析方法类似于JQ。API非常用户友好,支持CSS选择器;lxml的语法有一定的学习成本
2.performance:beautifulsoup基于DOM。它将加载整个文档并解析整个DOM树,因此时间和内存开销将大得多;Lxml只在本地进行遍历。此外,lxml是用C编写的,而Beauty soup是用Python编写的。显然,lxml>>;美丽的乌苏
综上所述,用靓汤更简洁,更容易使用。虽然lxml有一定的学习成本,但它也非常简洁易懂。最重要的是,它是用C编写的,速度要快得多。对于作者的强迫症,选择lxml是很自然的
03#json
Python自带了自己的JSON库,对于处理基本JSON来说已经足够了。但是,如果您想变得更懒惰,可以使用第三方JSON库。常见的是demjson和simplejson
这两个库在导入模块速度、编码和解码速度以及更好的兼容性方面都优于simplejson。因此,如果您想使用square库,可以使用simplejson
0x2确定语料库源
武器准备好后,下一步是确定攀爬方向
以电子体育语料库为例。现在我们将攀登电子体育语料库。常见的电子竞技平台包括企鹅电子竞技、企鹅电子竞技和企鹅电子竞技(斜视),因此我们使用企鹅电子竞技上的实时游戏作为爬行的数据源
我们登录企鹅电子竞技的官方网站,进入游戏列表页面。我们可以发现页面上有很多游戏。手动编写这些游戏名称显然是无利可图的,因此我们开始了爬虫程序的第一步:游戏列表爬虫
import requests
from lxml import etree
# 更新游戏列表
def _updateGameList():
# 发送HTTP请求时的HEAD信息,用于伪装为浏览器
heads = {
'Connection': 'Keep-Alive',
'Accept': 'text/html, application/xhtml+xml, */*',
'Accept-Language': 'en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3',
'Accept-Encoding': 'gzip, deflate',
'User-Agent': 'Mozilla/6.1 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko'
}
# 需要爬取的游戏列表页
url = 'https://egame.qq.com/gamelist'
# 不压缩html,最大链接时间为10妙
res = requests.get(url, headers=heads, verify=False, timeout=10)
# 为防止出错,编码utf-8
res.encoding = 'utf-8'
# 将html构建为Xpath模式
root = etree.HTML(res.content)
# 使用Xpath语法,获取游戏名
gameList = root.xpath("//ul[@class='livelist-mod']//li//p//text()")
# 输出爬到的游戏名
print(gameList)
当我们得到这几十个游戏名称时,下一步就是抓取这几十个游戏的语料库。此时,问题出现了。在推出这几十款游戏之前,我们将攀登哪个网站的顶峰?水龙头?多玩点?17173?通过分析这些网站s,发现这些网站s只有一些流行游戏的文章语料库,以及一些不受欢迎或低流行的游戏,如“灵魂芯片”、“奇迹:觉醒”和“死亡即将来临”。在这些网站s上很难找到大量的文章corpora,如图所示:
我们可以发现《奇迹:觉醒》和《灵魂芯片》的文章语料库非常少,数量也不符合我们的要求。那么,是否有一个更通用的资源站,它拥有无与伦比的丰富的文章语料库来满足我们的需求呢
事实上,冷静下来想想。我们每天都使用这个资源站,就是百度。我们在百度新闻中搜索相关游戏,并获得搜索结果列表。这些列表中几乎所有链接的网页都与搜索结果密切相关。这样,我们的数据源不够丰富的问题就可以很容易地得到解决。但是现在有一个新的问题,也是一个很难解决的问题——如何抓住任何网页的文章内容
因为不同的网站具有不同的页面结构,我们无法预测我们将爬升哪个网站数据,也无法为每个网站编写一组爬虫程序网站. 那种工作量是无法想象的!但我们不能简单粗暴地把这一页上的所有单词都写下来。用这样的语料库训练真是一场噩梦
经过与各种网站智慧和勇气的较量,查询数据和思考,我们终于找到了一个更通用的方案。让我们谈谈作者的想法
0x3任意网站爬网文章语料库
01|提取方法
@基于DOM树的1)文本提取
@基于网页分割的2)find文本块
@基于标记窗口的3)文本提取
4)基于数据挖掘或机器学习
@基于线块分布函数的5)文本提取
02|提取原理
我们看到这些都有点困惑,他们到底是怎么提取的呢?让我慢慢说
@基于1)DOM树的文本提取:
这种方法主要是通过比较标准HTML建立DOM树,然后遍历DOM,比较和识别各种非文本信息,包括广告、链接和非重要节点信息。提取出非文本信息后,剩下的自然是文本信息
但这种方法有两个问题
① 这尤其取决于HTML的良好结构。如果我们访问的网页不是按照W3C规范编写的,那么这种方法就不太适用
② 树的建立和遍历的时间复杂度和空间复杂度都很高,而且由于HTML标记的不同,树的遍历方法也会有所不同
2)find基于网页分段的文本块:
此方法使用HTML标记中的拆分行和一些视觉信息(如文本颜色、字体大小、文本信息等)
这种方法存在一个问题:
① 不同网站HTML风格迥异,没有统一的切分方法,不能保证切分的普遍性
3)基于标记窗口的文本提取:
首先介绍一个概念标签窗口。我们将两个标记和其中收录的文本组合到一个标记窗口中(例如,I am H1中的“I am H1”是标记窗口的内容),并取出标记窗口的文本
此方法首先获取HTML中的文章标题和所有标记窗口,然后将它们划分为单词。然后计算标题序列和标记窗口文本序列之间的单词距离L。如果l小于阈值,则标记窗口中的文本被视为文本
虽然这种方法看起来不错,但也存在一些问题:
① 对页面上的所有文本进行分段是没有效率的
② 单词距离的阈值很难确定,不同的单词文章具有不同的阈值
4)基于数据挖掘或机器学习
使用大数据进行培训,让机器提取主要文本
这种方法当然非常优秀,但它首先需要HTML和文本数据,然后再进行培训。我们不在这里讨论
@基于线块分布函数的5)文本提取
对于任何网页,其文本和标记总是混合在一起。此方法的核心有几个亮点:① 文本区域的密度;② 行块长度;网页的文本区域必须是文本信息分布最密集的区域之一。该区域可能最大(长评论信息和短文本),因此同时引用块长度进行判断
实施思路:
① 首先删除HTML标记,在取出标签后只留下所有文本和所有空白位置信息。我们称之为CText
② 取每个CText的周围K行(K)
③ 从cblock中删除所有空白字符,文本的总长度称为clen
④ 协调人