c爬虫抓取网页数据(第一点没什么捷径可走,或许可以给你省不少事)
优采云 发布时间: 2021-12-27 08:00c爬虫抓取网页数据(第一点没什么捷径可走,或许可以给你省不少事)
爬虫爬取数据有两个头疼的问题。写过爬虫的人一定深有体会:
网站的反爬虫机制。你要尽量伪装成“一个人”来欺骗对方的服务器进行反爬验证。
提取网站内容。每个网站都需要您做不同的处理,一旦网站被修改,您的代码必须相应更新。
第一点是没有捷径可走。如果你看到很多套路,你就会有经验。关于第二点,今天我们来介绍一个小工具。在一些需求场景下,它可能会为你节省很多事情。
鹅
Goose是一款文章内容提取器,可以从任意信息文章网页中提取文章主体,提取标题、标签、摘要、图片、视频等信息,支持中文网页。它最初是用 Java 编写的。python-goose 是一个用 Python 重写的版本。
有了这个库,你就可以直接从网上抓取下来的网页正文内容,无需使用bs4或正则表达式对文本进行一一处理。
项目地址:
(Py2)
(Py3)
安装
网上大部分教程中提到的python-goose项目目前只支持python2.7。它可以通过 pip 安装:
pip install goose-extractor
或者从官网源码安装方法:
mkvirtualenv --no-site-packages goose
git clone https://github.com/grangier/python-goose.git
cd python-goose
pip install -r requirements.txt
python setup.py install
我找到了一个python 3版本的goose3:
pip install goose3
经过一些简单的测试,我没有发现两个版本之间的结果有太大差异。
快速上手
这里用的是goose3,python-goose只需要把goose3改成goose就可以了,界面是一样的。以一篇文章为爬取目标进行演示。
from goose3 import Goose
from goose3.text import StopWordsChinese
# 初始化,设置中文分词
g = Goose({'stopwords_class': StopWordsChinese})
# 文章地址
url = 'https://mp.weixin.qq.com/s/zflbcF5PS06QC5YJXpiviQ'
# 获取文章内容
article = g.extract(url=url)
# 标题
print('标题:', article.title)
# 显示正文
print(article.cleaned_text)
输出:
除了标题和正文cleaned_text,还可以获得一些额外的信息,比如:
如果某些网站限制了程序爬取,您还可以根据需要添加user-agent信息:
g = Goose({'browser_user_agent': 'Version/5.1.2 Safari/534.52.7'})
如果是goose3,因为使用requests库作为请求模块,headers、proxy等属性也可以类似的配置。
上面例子中使用的StopWordsChinese是中文分词器,可以在一定程度上提高中文文章的识别准确率,但是比较耗时。
其他说明
1.
Goose虽然方便,但不保证每个网站都能准确获取,所以适用于热点追踪、舆情分析等*敏*感*词*文章采集,只能概率保证大部分网站可以爬行比较准确。经过一些尝试,我发现爬取英文网站优于中文网站,主流网站优于小众网站,文本提取优于图像提取。
2.
从项目中的requirements.txt文件可以看出goose中使用了Pillow、lxml、cssselect、jieba、beautifulsoup、nltk,goose3中也使用了requests。
3.
如果你使用的是基于python2的goose,你可能会遇到编码问题(尤其是在windows上)。
4.
除了goose,还有其他文本提取库可以尝试,比如python-boilerpipe、python-readability等。
实例
最后我们用goose3写一小段代码,自动抓取爱范儿、雷锋网、DoNews上的新闻文章:
from goose3 import Goose
from goose3.text import StopWordsChinese
from bs4 import BeautifulSoup
g = Goose({'stopwords_class': StopWordsChinese})
urls = [
'https://www.ifanr.com/',
'https://www.leiphone.com/',
'http://www.donews.com/'
]
url_articles = []
for url in urls:
page = g.extract(url=url)
soup = BeautifulSoup(page.raw_html, 'lxml')
links = soup.find_all('a')
for l in links:
link = l.get('href')
if link and link.startswith('http') and any(c.isdigit() for c in link if c) and link not in url_articles:
url_articles.append(link)
print(link)
for url in url_articles:
try:
article = g.extract(url=url)
content = article.cleaned_text
if len(content) > 200:
title = article.title
print(title)
with open('homework/goose/' + title + '.txt', 'w') as f:
f.write(content)
except:
pass
这个程序的作用是: