爬蟲練習-爬取簡書網熱評文章

前言:

使用多進程爬蟲方法爬取簡書網熱評文章,並將爬取的數據存儲於MongoDB數據庫中

本文爲整理代碼,梳理思路,驗證代碼有效性——2020.1.17


環境:
Python3(Anaconda3)
PyCharm
Chrome瀏覽器

主要模塊: 後跟括號內的爲在cmd窗口安裝的指令
requests(pip install requests)
lxml(pip install lxml)
re
pymongo(pip install pymongo )
multiprocessing
proxiesIp(自定義的IP代理池庫,可以不要)

1

爬取簡述網熱門文章信息(用戶ID、標題、文章內容、評論數、點贊數、打賞數)
在這裏插入圖片描述

2

2.1.通過觀察可以發現該網頁沒有具體的分頁,一直滑動頁面可以一直瀏覽,由此可以判斷該頁面爲異步加載(即不刷新整個網頁,只進行局部的更新加載)。

2.2.打開開發者工具 F12 按Network選項,並滾動頁面,我們發現請求返回了一些數據,而這些數據里正有我們需要訪問的真實URL,由此我可以構造相應的url列表解析式。
在這裏插入圖片描述

3

我們需要以下文章信息:用戶ID、標題、文章內容、評論數、點贊數、打賞數,使用XPath我們對該網頁進行解析。

在這裏插入圖片描述

# 用戶ID
author = info.xpath('div/div/a[1]/text()')[0]
# 文章標題
title = info.xpath('div/a/text()')[0]
# 文章內容
content = info.xpath('div/p/text()')[0].strip()
# 評論數
comment = info.xpath('div/div/a[2]/text()')[1].strip()
# 點贊數
like = info.xpath('div/div/span[2]/text()')[0].strip()
# 打賞數
rewards = info.xpath('div/div/span[3]/text()')
if len(rewards) == 0:
    reward = '無'
else:
    reward = rewards[0].strip()

因爲並非所有文章都有打賞,所以,我們對其進行判斷

4

使用多進程,首先導入使用多進程所需的庫

from multiprocessing import Pool

其次,創建進程池,這裏的processes是指同步發生的進程數量

測試發現,在爬取簡書網熱評文章時,processes越大,返回的HTTP狀態爲429(請求次數過多)的情況越多,這裏爲2時最佳。

pool = Pool(processes=2)

最後,調用進程爬蟲

調用進程爬蟲,這裏使用的是一個map函數,第一個參數是一個函數,第二個參數是一個列表,這裏的意思是將列表中的每個元素作用到前面這個函數中。

pool.map(get_jianshu_info, urls)

5

將數據插入到MongoDB數據庫中
5.1.首先,導入必要的pymongo庫

import pymongo

5.2.其次,連接並創建數據庫即數據集合

# 連接數據庫
client = pymongo.MongoClient('localhost', 27017)

# 創建數據庫和數據集合
mydb = client['mydb']
jianshu_shouye = mydb['jianshu_shouye']

5.3.最後插入數據到數據庫’jianshu_shouye‘中

data = { 'author':author,
         'title':title,
         'content':content,
         'comment':comment,
         'like':like,
         'reward':reward
         }
# 插入數據庫
jianshu_shouye.insert_one(data)

完整代碼

說明:該代碼僅爲了學習一下爬蟲技術,在url構造時只爬取兩頁,可自行修改。另,代理IP池(from proxiesIP_1_1 import proxiesIp)可以不要,測試時爲了防止被封IP加入的。還有有什麼問題可以在評論裏說明一下。

# 導入庫
import requests
from lxml import etree
import pymongo
from multiprocessing import Pool

from proxiesIP_1_1 import proxiesIp

# 連接數據庫
client = pymongo.MongoClient('localhost', 27017)

# 創建數據庫和數據集合
mydb = client['mydb']
jianshu_shouye = mydb['jianshu_shouye']

headers = {'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
                        'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36'}


# 定義獲取信息的函數
def get_jianshu_info(url):
    ip = proxiesIp.selectIp()
    html = requests.get(url=url, headers=headers, proxies=ip)
    print(url, html.status_code)

    selector = etree.HTML(html.text)
    # 獲取大標籤,以此循環
    infos = selector.xpath('//ul[@class="note-list"]/li')
    for info in infos:
        try:
            # 用戶ID
            author = info.xpath('div/div/a[1]/text()')[0]
            # 文章標題
            title = info.xpath('div/a/text()')[0]
            # 文章內容
            content = info.xpath('div/p/text()')[0].strip()
            # 評論數
            comment = info.xpath('div/div/a[2]/text()')[1].strip()
            # 點贊數
            like = info.xpath('div/div/span[2]/text()')[0].strip()
            # 打賞數
            rewards = info.xpath('div/div/span[3]/text()')
            if len(rewards) == 0:
                reward = '無'
            else:
                reward = rewards[0].strip()

            data = { 'author':author,
                     'title':title,
                     'content':content,
                     'comment':comment,
                     'like':like,
                     'reward':reward
                     }
            print(data)
            # 插入數據庫
            jianshu_shouye.insert_one(data)

        except IndexError:
            # pass掉IndexError錯誤
            pass


# 程序主入口
if __name__ == '__main__':
    urls = ['https://www.jianshu.com/c/bDHhpK?order_by=top&page={}'.format(str(i)) for i in range(1, 3)]
    # 創建進程池
    pool = Pool(processes=2)
    # 調用進程爬蟲
    pool.map(get_jianshu_info, urls)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章