當你在知乎上搜索一個話題,如王寶強的時候,搜索結果頁面的底部有個“更多”按鈕,如下圖
遇到這個坑爹了,因為你發(fā)現點擊“更多”按鈕后,網址部分沒有變化,但頁面卻加載了新的數據。怎么辦????
沒法按照之前的 有規(guī)律的網址&page=number ,通過for循環(huán)依次遍歷網頁。
在這里我不講抓包,分析請求包。咱們用生硬的方法,破解這問題。在這里我使用了selenium庫,并且要安裝一個火狐瀏覽器(firefox36)。輕松破解該問題。
selenium教程,建議大家網上買《selenium 2自動化測試實戰(zhàn)-基于python語言》 這本書閱讀相關知識。當然也可以根據本代碼,在網上查相關selenium的知識。
import re
import csv
import time
import urllib.parse as parse
from selenium import webdriver
from bs4 import BeautifulSoup
# keyword話題名 ,filename保存數據的文件名,page_num收集多少頁
def topic_title_spider(keyword='王寶強', filename = 'wangbaoqiang', page_num = 10):
start = time.time()
# 建立一個收集數據的csv文件
csvFile = open(r'E:\%s.csv'% filename, 'a+', newline='')
writer = csv.writer(csvFile)
writer.writerow(('title', 'review_num'))
# 將關鍵詞轉換為十六進制格式,填入到鏈接中
kw = parse.quote(keyword)
driver = webdriver.Firefox()
driver.get('https://www.zhihu.com/search?type=content&q=%s' % kw)
# 正則表達式,用來匹配標題,評論數
reg_title = re.compile(r'<a class="js-title-link" href=.*?" target="_blank">(.*?)</a>')
reg_li = re.compile(r'item clearfix.*?')
reg_num = re.compile(r'<a class="zm-item-vote-count hidden-expanded js-expand js-vote-count" data-bind-votecount="">(.*?)</a>')
# 先循環(huán)點擊頁面底部“更多”,加載盡可能多的頁面數據
for i in range(1, page_num, 1):
driver.find_element_by_link_text("更多").click()
duration = time.time()-start
print('%s小爬蟲 已經跑到 第%d頁 了,運行時間%.2f秒,好累啊'%(keyword, i, duration))
time.sleep(5)
soup = BeautifulSoup(driver.page_source, 'lxml')
li_s = soup.find_all('li', {'class': reg_li})
for li in li_s:
li = str(li)
try:
title = re.findall(reg_title, li)[0]
title = title.replace('<em>', '')
title = title.replace('</em>', '')
review_num = re.findall(reg_num, li)[0]
except:
continue
writer.writerow((title, review_num))
print(title, review_num)
csvFile.close()
driver.quit()
代碼在我這里運行成功,不過在你那里需要注意拷貝代碼后,要調整代碼,因為有的代碼一行太長了,被知乎調整到第二行了,這樣可能會出錯。
該方法缺點是運行速度慢,不過對于小數據需求的小白們來說,還是可以接受的。