Python怎么進(jìn)行簡(jiǎn)單的百度新聞爬取

Python怎么進(jìn)行簡(jiǎn)單的百度新聞爬取,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。

曹妃甸網(wǎng)站制作公司哪家好,找成都創(chuàng)新互聯(lián)公司!從網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、響應(yīng)式網(wǎng)站等網(wǎng)站項(xiàng)目制作,到程序開發(fā),運(yùn)營(yíng)維護(hù)。成都創(chuàng)新互聯(lián)公司2013年開創(chuàng)至今到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來(lái)保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選成都創(chuàng)新互聯(lián)公司。

這個(gè)實(shí)戰(zhàn)例子是構(gòu)建一個(gè)大規(guī)模的異步新聞爬蟲,但要分幾步走,從簡(jiǎn)單到復(fù)雜,循序漸進(jìn)的來(lái)構(gòu)建這個(gè)Python爬蟲

本教程所有代碼以Python 3.6實(shí)現(xiàn),不兼顧Python 2,強(qiáng)烈建議大家使用Python 3

Python怎么進(jìn)行簡(jiǎn)單的百度新聞爬取

要抓取新聞,首先得有新聞源,也就是抓取的目標(biāo)網(wǎng)站。國(guó)內(nèi)的新聞網(wǎng)站,從中央到地方,從綜合到垂直行業(yè),大大小小有幾千家新聞網(wǎng)站。百度新聞(news.baidu.com)收錄的大約兩千多家。那么我們先從百度新聞入手。

打開百度新聞的網(wǎng)站首頁(yè): news.baidu.com
我們可以看到這就是一個(gè)新聞聚合網(wǎng)頁(yè),里面列舉了很多新聞的標(biāo)題及其原始鏈接。如圖所示:

Python怎么進(jìn)行簡(jiǎn)單的百度新聞爬取

我們的目標(biāo)就是從這里提取那些新聞的鏈接并下載。流程比較簡(jiǎn)單:

Python怎么進(jìn)行簡(jiǎn)單的百度新聞爬取

新聞爬蟲簡(jiǎn)單流程圖

根據(jù)這個(gè)簡(jiǎn)單流程,我們先實(shí)現(xiàn)下面的簡(jiǎn)單代碼:

#!/usr/bin/env python3
# Author: veelion
import re
import time
import requests
import tldextract
def save_to_db(url, html):
    # 保存網(wǎng)頁(yè)到數(shù)據(jù)庫(kù),我們暫時(shí)用打印相關(guān)信息代替
    print('%s : %s' % (url, len(html)))
def crawl():
    # 1\. download baidu news
    hub_url = 'http://news.baidu.com/'
    res = requests.get(hub_url)
    html = res.text
    # 2\. extract news links
    ## 2.1 extract all links with 'href'
    links = re.findall(r'href=[\'"]?(.*?)[\'"\s]', html)
    print('find links:', len(links))
    news_links = []
    ## 2.2 filter non-news link
    for link in links:
        if not link.startswith('http'):
            continue
        tld = tldextract.extract(link)
        if tld.domain == 'baidu':
            continue
        news_links.append(link)
    print('find news links:', len(news_links))
    # 3\. download news and save to database
    for link in news_links:
        html = requests.get(link).text
        save_to_db(link, html)
    print('works done!')
def main():
    while 1:
        crawl()
        time.sleep(300)
if __name__ == '__main__':
    main()

簡(jiǎn)單解釋一下上面的代碼:

1. 使用requests下載百度新聞首頁(yè);
2. 先用正則表達(dá)式提取a標(biāo)簽的href屬性,也就是網(wǎng)頁(yè)中的鏈接;然后找出新聞的鏈接,方法是:假定非百度的外鏈都是新聞鏈接;
3. 逐個(gè)下載找到的所有新聞鏈接并保存到數(shù)據(jù)庫(kù);保存到數(shù)據(jù)庫(kù)的函數(shù)暫時(shí)用打印相關(guān)信息代替。
4. 每隔300秒重復(fù)1-3步,以抓取更新的新聞。

以上代碼能工作,但也僅僅是能工作,槽點(diǎn)多得也不是一點(diǎn)半點(diǎn),那就讓我們一起邊吐槽邊完善這個(gè)爬蟲吧。

1. 增加異常處理

在寫爬蟲,尤其是網(wǎng)絡(luò)請(qǐng)求相關(guān)的代碼,一定要有異常處理。目標(biāo)服務(wù)器是否正常,當(dāng)時(shí)的網(wǎng)絡(luò)連接是否順暢(超時(shí))等狀況都是爬蟲無(wú)法控制的,所以在處理網(wǎng)絡(luò)請(qǐng)求時(shí)必須要處理異常。網(wǎng)絡(luò)請(qǐng)求最好設(shè)置timeout,別在某個(gè)請(qǐng)求耗費(fèi)太多時(shí)間。timeout 導(dǎo)致的識(shí)別,有可能是服務(wù)器響應(yīng)不過(guò)來(lái),也可能是暫時(shí)的網(wǎng)絡(luò)出問(wèn)題。所以,對(duì)于timeout的異常,我們需要過(guò)段時(shí)間再嘗試。

2. 要對(duì)服務(wù)器返回的狀態(tài),如404,500等做出處理

服務(wù)器返回的狀態(tài)很重要,這決定著我們爬蟲下一步該怎么做。需要處理的常見狀態(tài)有:

  • 301, 該URL被永久轉(zhuǎn)移到其它URL,以后請(qǐng)求的話就請(qǐng)求被轉(zhuǎn)移的URL

  • 404,基本上是這個(gè)網(wǎng)站已經(jīng)失效了,后面也就別試了

  • 500,服務(wù)器內(nèi)部出錯(cuò)了,可能是暫時(shí)的,后面要再次請(qǐng)求試試

3. 管理好URL的狀態(tài)

記錄下此次失敗的URL,以便后面再試一次。對(duì)于timeout的URL,需要后面再次抓取,所以需要記錄所有URL的各種狀態(tài),包括:

  • 已經(jīng)下載成功

  • 下載多次失敗無(wú)需再下載

  • 正在下載

  • 下載失敗要再次嘗試

增加了對(duì)網(wǎng)絡(luò)請(qǐng)求的各種處理,這個(gè)爬蟲就健壯多了,不會(huì)動(dòng)不動(dòng)就異常退出,給后面運(yùn)維帶來(lái)很多的工作量。
下一節(jié)我們講對(duì)上面三個(gè)槽點(diǎn)結(jié)合代碼一一完善。欲知詳情,請(qǐng)聽下回分解。


Python爬蟲知識(shí)點(diǎn)

本節(jié)中我們用到了Python的幾個(gè)模塊,他們?cè)谂老x中的作用如下:
1. requests模塊
它用來(lái)做http網(wǎng)絡(luò)請(qǐng)求,下載URL內(nèi)容,相比Python自帶的urllib.request,requests更加易用。GET,POST信手拈來(lái):

import requests
res = requests.get(url, timeout=5, headers=my_headers)
res2 = requests.post(url, data=post_data, timeout=5, headers=my_headers)

get()和post()函數(shù)有很多參數(shù)可選,上面用到了設(shè)置timeout,自定義headers,更多參數(shù)可參考requests 文檔。

requests無(wú)論get()還是post()都會(huì)返回一個(gè)Response對(duì)象,下載到的內(nèi)容就通過(guò)這個(gè)對(duì)象獲?。?/p>

  • res.content 是得到的二進(jìn)制內(nèi)容,其類型是bytes;

  • res.text 是二進(jìn)制內(nèi)容content decode后的str內(nèi)容;
    它先從response headers里面找到encoding,沒(méi)找到就通過(guò)chardet自動(dòng)判斷得到encoding,并賦值給res.encoding,最后把二進(jìn)制的content解密為str類型。

經(jīng)驗(yàn)之談: res.text判斷中文編碼時(shí)有時(shí)候會(huì)出錯(cuò),還是自己通過(guò)cchardet(用C語(yǔ)言實(shí)現(xiàn)的chardet)獲取更準(zhǔn)確。這里,我們列舉一個(gè)例子:

In [1]: import requests
In [2]: r = requests.get('http://epaper.sxrb.com/')
In [3]: r.encoding
Out[3]: 'ISO-8859-1'
In [4]: import chardet
In [5]: chardet.detect(r.content)
Out[5]: {'confidence': 0.99, 'encoding': 'utf-8', 'language': ''}

上面是用ipython交互式解釋器(強(qiáng)烈推薦ipython,比Python自己的解釋器好太多)演示了一下。打開的網(wǎng)址是山西日?qǐng)?bào)數(shù)字報(bào),手動(dòng)查看網(wǎng)頁(yè)源碼其編碼是utf8,用chardet判斷得到的也是utf8。而requests自己判斷的encoding是ISO-8859-1,那么它返回的text的中文也就會(huì)是亂碼。

requests還有個(gè)好用的就是Session,它部分類似瀏覽器,保存了cookies,在后面需要登錄和與cookies相關(guān)的爬蟲都可以用它的session來(lái)實(shí)現(xiàn)。

2. re模塊

正則表達(dá)式主要是用來(lái)提取html中的相關(guān)內(nèi)容,比如本例中的鏈接提取。更復(fù)雜的html內(nèi)容提取,推薦使用lxml來(lái)實(shí)現(xiàn)。

3. tldextract模塊

這是個(gè)第三方模塊,需要pip install tldextract進(jìn)行安裝。它的意思就是Top Level Domain extract,即頂級(jí)域名提取。前面我們講過(guò)URL的結(jié)構(gòu),news.baidu.com 里面的news.baidu.com叫做host,它是注冊(cè)域名baidu.com的子域名,而com就是頂級(jí)域名TLD。它的結(jié)果是這樣的:

In [6]: import tldextract
In [7]: tldextract.extract('http://news.baidu.com/')
Out[7]: ExtractResult(subdomain='news', domain='baidu', suffix='com')

返回結(jié)構(gòu)包含三部分:subdomain, domain, suffix

4. time模塊

時(shí)間,是我們?cè)诔绦蛑薪?jīng)常用到的概念,比如,在循環(huán)中停頓一段時(shí)間,獲取當(dāng)前的時(shí)間戳等。而time模塊就是提供時(shí)間相關(guān)功能的模塊。同時(shí)還有另外一個(gè)模塊datetime也是時(shí)間相關(guān)的,可以根據(jù)情況適當(dāng)選擇來(lái)用。

記住這幾個(gè)模塊,在今后的寫爬蟲生涯中將會(huì)受益匪淺。

看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對(duì)創(chuàng)新互聯(lián)的支持。

本文題目:Python怎么進(jìn)行簡(jiǎn)單的百度新聞爬取
文章分享:http://muchs.cn/article20/jojhjo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供響應(yīng)式網(wǎng)站企業(yè)建站、營(yíng)銷型網(wǎng)站建設(shè)、網(wǎng)站導(dǎo)航、建站公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)公司