文章內容提取庫 goose 簡介

爬蟲抓取數據有兩個頭疼的點,寫過爬蟲的小夥伴們必定都深有體會:css

  1. 網站的 防抓取 機制。你要儘量將本身假裝成「一我的」,騙過對方的服務器反爬驗證。
  2. 網站的 內容提取 。每一個網站都須要你作不一樣的處理,並且網站一旦改版,你的代碼也得跟着更新。

第一點沒什麼捷徑可走,套路見得多了,也就有經驗了。關於第二點,今天我們就來介紹一個小工具,在某些需求場景下,或許能夠給你省很多事。html

Goose

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 的版本 goose3windows

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 外,還能夠獲取一些額外的信息,好比:

  • meta_description :摘要
  • meta_keywords :關鍵詞
  • tags :標籤
  • top_image :主要圖片
  • infos :包含全部信息的 dict
  • raw_html :原始 HTML 文本

若有有些網站限制了程序抓取,也能夠根據須要添加 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

這段程序所作的事情就是:

  1. 抓取網站首頁
  2. 從頁面上提取地址中帶有數字的連接(由於文章頁基本帶數字,這裏爲了演示簡單以此判斷)
  3. 抓取這些連接,提取正文。若是結果超過 200 個字,就保存成文件

效果:

在此基礎上,你能夠繼續改進這個程序,讓它不停地去尋找新的地址並抓取文章,並對獲取到的文章進行詞頻統計、生成詞雲等後續操做。相似咱們以前的分析案例 數據分析:當趙雷唱民謠時他唱些什麼?。進一步完善,相信你能作出更有意思的項目。

相關代碼已上傳,獲取地址請在公衆號( Crossin的編程教室 )裏回覆關鍵字 goose

════
其餘文章及回答:
如何自學Python | 新手引導 | 精選Python問答 | 如何debug? | Python單詞表 | 知乎下載器 | 人工智能 | 嘻哈 | 爬蟲 | 我用Python | 高考 | requests | AI平臺

歡迎微信搜索及關注: Crossin的編程教室

相關文章
相關標籤/搜索