爬虫抓取数据有两个头疼的点,写过爬虫的小伙伴们必定都深有体会:css
第一点没什么捷径可走,套路见得多了,也就有经验了。关于第二点,今天我们就来介绍一个小工具,在某些需求场景下,或许能够给你省很多事。html
Goose 是一个 文章内容提取器 ,能够从任意资讯文章类的网页中提取 文章主体 ,并提取 标题、标签、摘要、图片、视频 等信息,且 支持中文 网页。它最初是由 http://Gravity.com 用 Java 编写的。python-goose 是用 Python 重写的版本。python
有了这个库,你从网上爬下来的网页能够直接获取正文内容,无需再用 bs4 或正则表达式一个个去处理文本。git
项目地址:
(py2) https://github.com/grangier/python-goose
(py3) https://github.com/goose3/goose3github
网上大多数教程提到的 python-goose 项目目前只支持到 python 2.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 :windows
pip install goose3
通过我一些简单的测试,未发现两个版本在结果上有太大的差别。服务器
快速上手微信
这里使用 goose3,而 python-goose 只要把其中的 goose3 改为 goose 便可,接口都是同样的。以我以前发过的一篇文章 如何用Python抓抖音上的小姐姐 为抓取目标来作个演示。
from goose3 import Goose from goose3.text import StopWordsChinese # 初始化,设置中文分词 g = Goose({'stopwords_class': StopWordsChinese}) # 文章地址 url = 'http://zhuanlan.zhihu.com/p/46396868' # 获取文章内容 article = g.extract(url=url) # 标题 print('标题:', article.title) # 显示正文 print(article.cleaned_text)
输出:
除了标题 title 和正文 cleaned_text 外,还能够获取一些额外的信息,好比:
若有有些网站限制了程序抓取,也能够根据须要添加 user-agent 信息:
g = Goose({'browser_user_agent': 'Version/5.1.2 Safari/534.52.7'})
若是是 goose3,由于使用了 requests 库做为请求模块,所以还能够以类似方式配置 headers、proxies 等属性。
在上述示例中使用到的 StopWordsChinese
为中文分词器,可必定程度上提升中文文章的识别准确率,但更耗时。
Goose 虽然方便,但并不能保证每一个网站都能精确获取,所以 适合大规模文章的采集 ,如热点追踪、舆情分析等。它只能从几率上保证大多数网站能够相对准确地抓取。我通过一些尝试后发现,抓取英文网站优于中文网站,主流网站优于小众网站,文本的提取优于图片的提取。
从项目中的 requirements.txt 文件能够看出,goose 中使用到了 Pillow、lxml、cssselect、jieba、beautifulsoup、nltk ,goose3 还用到了 requests ,咱们以前不少文章和项目中都有所涉及:
这个男人让你的爬虫开发效率提高8倍
【编程课堂】jieba-中文分词利器
若是你是使用基于 python2 的 goose,有可能会遇到 编码 上的问题(尤为是 windows 上)。这方面能够在公众号对话里回复关键词 编码 ,咱们有过相关的讲解。
除了 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
这段程序所作的事情就是:
效果:
在此基础上,你能够继续改进这个程序,让它不停地去寻找新的地址并抓取文章,并对获取到的文章进行词频统计、生成词云等后续操做。相似咱们以前的分析案例 数据分析:当赵雷唱民谣时他唱些什么?。进一步完善,相信你能作出更有意思的项目。
相关代码已上传,获取地址请在公众号( Crossin的编程教室 )里回复关键字 goose
════
其余文章及回答:
如何自学Python | 新手引导 | 精选Python问答 | 如何debug? | Python单词表 | 知乎下载器 | 人工智能 | 嘻哈 | 爬虫 | 我用Python | 高考 | requests | AI平台
欢迎微信搜索及关注: Crossin的编程教室