1. 程式人生 > 其它 >python抓取頭條文章

python抓取頭條文章

最近做了個專案,希望把運營同學在今日頭條上發的文章自動釋出到公司的官方部落格中去,然後可以人工篩選需要釋出的文章~

很明顯,要實現這功能,就需要程式自動抓取頭條號釋出過的文章(文字、圖片、視訊等元素),然後插入到部落格後臺的資料庫。

單說爬蟲,分定向爬蟲和全網爬蟲。除了搜尋引擎會使用全網爬蟲,大部分自己寫的爬蟲都是定向爬蟲,比如抓取豆瓣電影資料,抓取youtube視訊,或者今天要說的抓取頭條文章等。

因為python有很多專門實現爬蟲的庫,比如urllib,requests,scrapy,grab等,所以首選python進行抓取。

1、尋找url規律

這裡我找了個頭條號主頁:http://www.toutiao.com/c/user/6493820122/#mid=6493820122,通過瀏覽器中請求,發現頁面資料是非同步載入的,如下:

開啟這個請求,並去掉無用引數,得出如下api地址:

http://www.toutiao.com/c/user/article/?page_type=1&user_id=6493820122&max_behot_time=0&count=20

引數說明:

page_type: 文章型別,1應該是圖文型別,0代表視訊型別;

user_id: 這個不用說,是頭條號的唯一標識;

max_behot_time: 獲取下一頁資料的標識時間戳,0代表獲取第一頁資料,時間戳值就代表獲取這條資料以後的資料;

count: 每頁返回多少條,預設20條;

url規律已經找到,獲取下一頁資料,只需修改max_behot_time的值即可~

2、模擬請求,獲取資料

模擬請求方式比較多,我這裡就直接用requests了,如下:

url = 'http://www.toutiao.com/c/user/article/?page_type=1&user_id=6820944107&max_behot_time=%d&count=20' % max_behot_time
result = requests.get(url)
text = json.loads(result.text)

json資料很好處理,直接獲取,入庫即可。問題是這個列表資料只返回了title,time等欄位,並沒有返回文章詳細內容,標籤等元素。所以還要再進入詳情頁,獲取詳細內容。

3、處理返回資料 & 入庫

詳情頁資料返回後,你會發現返回結果是HTML,這就和上面直接返回json資料的處理方式不一樣了,獲取HTML中的元素內容,常見的方法是使用xpath進行匹配,但我們明顯是要獲取整個頁面中包含HTML元素的文章內容,顯然xpath很難做到這點兒。

好吧,換一個提取資料的Python庫吧——BeautifulSoup,寫法比較像jquery選取節點,非常實用。

url = 'http://www.toutiao.com%s' % r['source_url']
result = requests.get(url)
text = result.content
soup = BeautifulSoup(text)
article = soup.find(attrs={'class', 'article-content'})
article = article.contents[0]
article = article.encode('utf-8')

labels = soup.find_all(attrs={'class', 'label-item'})

find()方法返回一條匹配資料,find_all()則返回所有匹配結果,然後寫入mongo:

db.toutiao.update({"_id": id, {"$set": {"article": article, ...}})

4、寫個定時任務或者手動觸發

以上程式碼雖然實現了抓取資料併入庫,但是,需要每次執行指令碼才能抓取,如果你有時間,建議寫個定時任務,或者在管理後臺上新增“一鍵抓取”的按鈕來觸發:

while True:
    current_time = time.localtime(time.time())
    if (current_time.tm_hour == 6) and (current_time.tm_min == 0):
        print "================ 開始執行指令碼: ================"
        spider_article()
    time.sleep(1)

當然,如果你抓取的內容比較多,你也可以建立叢集進行爬取~以上也並沒有寫下載圖片和視訊的功能,感興趣的同學,私下討論~