亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python怎么進行簡單的百度新聞爬取

發布時間:2021-10-25 18:33:52 來源:億速云 閱讀:456 作者:柒染 欄目:編程語言

Python怎么進行簡單的百度新聞爬取,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

這個實戰例子是構建一個大規模的異步新聞爬蟲,但要分幾步走,從簡單到復雜,循序漸進的來構建這個Python爬蟲

本教程所有代碼以Python 3.6實現,不兼顧Python 2,強烈建議大家使用Python 3

Python怎么進行簡單的百度新聞爬取

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

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

Python怎么進行簡單的百度新聞爬取

我們的目標就是從這里提取那些新聞的鏈接并下載。流程比較簡單:

Python怎么進行簡單的百度新聞爬取

新聞爬蟲簡單流程圖

根據這個簡單流程,我們先實現下面的簡單代碼:

#!/usr/bin/env python3
# Author: veelion
import re
import time
import requests
import tldextract
def save_to_db(url, html):
    # 保存網頁到數據庫,我們暫時用打印相關信息代替
    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()

簡單解釋一下上面的代碼:

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

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

1. 增加異常處理

在寫爬蟲,尤其是網絡請求相關的代碼,一定要有異常處理。目標服務器是否正常,當時的網絡連接是否順暢(超時)等狀況都是爬蟲無法控制的,所以在處理網絡請求時必須要處理異常。網絡請求最好設置timeout,別在某個請求耗費太多時間。timeout 導致的識別,有可能是服務器響應不過來,也可能是暫時的網絡出問題。所以,對于timeout的異常,我們需要過段時間再嘗試。

2. 要對服務器返回的狀態,如404,500等做出處理

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

  • 301, 該URL被永久轉移到其它URL,以后請求的話就請求被轉移的URL

  • 404,基本上是這個網站已經失效了,后面也就別試了

  • 500,服務器內部出錯了,可能是暫時的,后面要再次請求試試

3. 管理好URL的狀態

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

  • 已經下載成功

  • 下載多次失敗無需再下載

  • 正在下載

  • 下載失敗要再次嘗試

增加了對網絡請求的各種處理,這個爬蟲就健壯多了,不會動不動就異常退出,給后面運維帶來很多的工作量。
下一節我們講對上面三個槽點結合代碼一一完善。欲知詳情,請聽下回分解。


Python爬蟲知識點

本節中我們用到了Python的幾個模塊,他們在爬蟲中的作用如下:
1. requests模塊
它用來做http網絡請求,下載URL內容,相比Python自帶的urllib.request,requests更加易用。GET,POST信手拈來:

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()函數有很多參數可選,上面用到了設置timeout,自定義headers,更多參數可參考requests 文檔。

requests無論get()還是post()都會返回一個Response對象,下載到的內容就通過這個對象獲取:

  • res.content 是得到的二進制內容,其類型是bytes;

  • res.text 是二進制內容content decode后的str內容;
    它先從response headers里面找到encoding,沒找到就通過chardet自動判斷得到encoding,并賦值給res.encoding,最后把二進制的content解密為str類型。

經驗之談: res.text判斷中文編碼時有時候會出錯,還是自己通過cchardet(用C語言實現的chardet)獲取更準確。這里,我們列舉一個例子:

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交互式解釋器(強烈推薦ipython,比Python自己的解釋器好太多)演示了一下。打開的網址是山西日報數字報,手動查看網頁源碼其編碼是utf8,用chardet判斷得到的也是utf8。而requests自己判斷的encoding是ISO-8859-1,那么它返回的text的中文也就會是亂碼。

requests還有個好用的就是Session,它部分類似瀏覽器,保存了cookies,在后面需要登錄和與cookies相關的爬蟲都可以用它的session來實現。

2. re模塊

正則表達式主要是用來提取html中的相關內容,比如本例中的鏈接提取。更復雜的html內容提取,推薦使用lxml來實現。

3. tldextract模塊

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

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

返回結構包含三部分:subdomain, domain, suffix

4. time模塊

時間,是我們在程序中經常用到的概念,比如,在循環中停頓一段時間,獲取當前的時間戳等。而time模塊就是提供時間相關功能的模塊。同時還有另外一個模塊datetime也是時間相關的,可以根據情況適當選擇來用。

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

看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

延吉市| 远安县| 宿州市| 隆昌县| 长治市| 汽车| 丹寨县| 綦江县| 忻城县| 三明市| 神池县| 富平县| 玉环县| 旬阳县| 河曲县| 驻马店市| 宜兴市| 佛山市| 房山区| 商都县| 抚远县| 株洲县| 西林县| 东乡| 原平市| 奉贤区| 崇文区| 望都县| 霍城县| 凌云县| 封开县| 绥化市| 富宁县| 宜城市| 娄烦县| 疏附县| 宜昌市| 额尔古纳市| 博乐市| 古田县| 腾冲县|