【Python3】利用selenium抓取知乎用戶的文章

【Python3】利用selenium抓取知乎用戶的文章

來自專欄 Python程序員24 人贊了文章

【背景】

前段時間,閱讀知乎上一些用戶寫的文章的時候覺得閱讀起來比較麻煩,不符合我的閱讀感受。比如下邊這個,我想閱讀牛客網的文章(如圖1所示),我會通過標題先進行篩選,但是這樣滾動下滑太麻煩了,所以想著不如將標題信息爬下來,另外,點贊數和評論數也順便抓取下來,這樣還能看該用戶被點贊數最多的文章是哪一篇。說干就干!

圖1 知乎用戶牛客網的文章

【思路】

利用selenium抓取知乎用戶的文章頁面源碼,接著用pyquery庫來解析文章相關信息,並將其保存到MongoDB資料庫中,通過MongoDB Compass這個可視化工具可以可視化的操作資料庫,還可以進行數據的導入導出。

【涉及知識點】

  • 基本庫的使用
  • selenium庫、pyquery庫、pymongo庫的使用
  • CSS selector的使用
  • 正則表達式

【預裝庫及軟體】

  • 首先確保自己的電腦安裝了MongoDB資料庫。
  • MongoDB Compass軟體自己視情況而定,如果常用命令行操作資料庫的話,這個可以不安裝,對我們的數據抓取沒有影響。
  • 確保你的Python3環境中有下邊幾個庫,pymongo、selenium和pyquery要自己安裝,可以直接用pip進行安裝。

import reimport timeimport pymongofrom selenium import webdriverfrom selenium.common.exceptions import TimeoutExceptionfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.support import expected_conditions as ECfrom selenium.webdriver.support.wait import WebDriverWaitfrom pyquery import PyQuery as pq

【網頁分析】

  • 首先找到知乎用戶牛客網的文章列表的鏈接(如圖2所示),可以看到總共280篇文章。拉到頁面底部可以看到文章列表共有14頁(如圖3所示)。

圖2 知乎用戶牛客網的文章列錶鏈接

圖3 文章列表頁面數

  • 當我們點下一頁,頁面跳轉到第二頁時,可以看到網頁鏈接變成「/org/niu-ke-wang-53/posts?page=2」,這樣的話,我們可以通過改變傳入參數「page」的值來請求這14個頁面。
  • 我們使用selenium來模擬瀏覽器打開網頁,這裡使用 WebDriverWait 來等待頁面載入完網頁之後再進行別的處理工作。還可以注意到這樣一件事,頁面載入完成的時候頁面是沒有全部顯示的,隨著滑鼠向下滾動才載入出來頁面的全部信息。通過如下代碼可以模仿滑鼠向下滾動到頁面底部。

browser.execute_script("window.scrollTo(0, document.body.scrollHeight)")

  • 載入出來頁面之後就可以抓取信息了。信息提取這部分主要有函數「get_posts()」來負責。我選擇抓取了文章標題、文章鏈接、文章作者、文章作者主頁鏈接、點贊人數以及評論數。
  • 最後由函數「save_to_mongo()」來將信息存儲進MongoDB資料庫中。
  • 用下邊的代碼來取代「browser = webdriver.Chrome()」可以實現瀏覽器不打開,在後台進行抓取工作。

chrome_options = webdriver.ChromeOptions()chrome_options.add_argument(--headless)browser = webdriver.Chrome(chrome_options=chrome_options)

  • 最後打開MongoDB Compass軟體可以看到「Documents」值為280,總共抓取了280篇文章的信息。

圖4 資料庫

【代碼實現】

MONGO_URL = localhostMONGO_DB = zhihuMONGO_COLLECTION = niukewang_postsMAX_PAGE = 14chrome_options = webdriver.ChromeOptions()chrome_options.add_argument(--headless)browser = webdriver.Chrome(chrome_options=chrome_options)# browser = webdriver.Chrome()wait = WebDriverWait(browser, 10)client = pymongo.MongoClient(MONGO_URL)db = client[MONGO_DB]def index_page(page): """ 抓取索引頁 :param page: 頁碼 """ print(正在爬取第, page, 頁) try: url = https://www.zhihu.com/org/niu-ke-wang-53/posts?page= + str(page) browser.get(url) wait.until( EC.text_to_be_present_in_element((By.CSS_SELECTOR, .Pagination .PaginationButton--current), str(page))) wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, .Profile-mainColumn .List .List-item))) browser.execute_script("window.scrollTo(0, document.body.scrollHeight)") time.sleep(3) get_posts() except TimeoutException: index_page(page)def get_posts(): """ 提取文章數據 """ html = browser.page_source doc = pq(html) items = doc(#Profile-posts .List-item).items() for item in items: urlstr = item.find(.ContentItem.ArticleItem).attr(data-zop) pattern = re.compile("itemId":(.*?),) urlid = re.findall(pattern, urlstr) commentstr = item.find(.ContentItem-actions .ContentItem-action.Button--plain).text() pattern = re.compile((d+)) commentnum = re.findall(pattern, commentstr) if len(commentnum) == 0: commentnum.append(0) niukewang_posts = { title: item.find(.ContentItem-title).text(), url: https://zhuanlan.zhihu.com/p/+urlid[0], authorname: item.find(.ContentItem-meta .AuthorInfo-content .UserLink-link).text(), authorurl: https:+str(item.find(.ContentItem-meta .AuthorInfo-content .UserLink-link).attr(href)), like: int(item.find(.ContentItem-actions .LikeButton).text()), commentnum: int(commentnum[0]) } print(niukewang_posts) save_to_mongo(niukewang_posts)def save_to_mongo(result): """ 保存至MongoDB :param result: 結果 """ try: if db[MONGO_COLLECTION].insert(result): print(存儲到MongoDB成功) except Exception: print(存儲到MongoDB失敗)def main(): """ 遍歷每一頁 """ for i in range(1, MAX_PAGE + 1): index_page(i) browser.close()if __name__ == __main__: main()

【成果展示】

下載好的信息按照條目存放到了本地MongoDB資料庫里(如圖5所示)。

圖5 表中前15條數據

用點贊數作為關鍵詞進行降序排列(如圖6所示),其中,點贊數最多的是「十面阿里,七面頭條,六個Offer,春招結束」這篇文章,有710個贊和83條評論。

圖6 點贊數最多前15篇文章數據

【後記】

寫文章的初衷也算是將自己的學習成果傳播給大家,來幫助大家學習,所以對我寫的這篇文章有什麼問題的歡迎詢問,同時,有錯誤的地方也歡迎批評指正~

後邊寫的多的話,會將代碼一一整理出來放到GitHub上,分享給大家~


推薦閱讀:

TAG:Selenium | 爬蟲計算機網路 | Python |