這里分享一個低配版知乎爬蟲,利用了Selenium模塊
爬取的過程中遇到了10002:請求參數異常,請升級客戶端后重試
,調用知乎某用戶的回答API返回的HTTP狀態碼是403 Forbidden
之后找了一篇博客,里面給出的解決方案是:使用自己打開的一個瀏覽器,再用selenium接管這個瀏覽器這樣就可以完成反爬的處理。
步驟
1
cmd切換到chrome.exe所在的目錄下,
(文件資源管理器內,到指定目錄下,在地址欄輸入cmd回車也行)
執行命令chrome.exe --remote-debugging-port=9222 --user-data-dir="E:\selenium_data"
其中--remote-debugging-port是建立新的移植位置,其中端口后面會使用(自定義), --user-data-dir是數據存儲的目錄(自定義)
2
運行py代碼爬取某用戶的回答
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
import time
import requests
from selenium.webdriver.common.keys import Keys
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
def load_photo(url, name):
'''給定圖片鏈接,將圖片以某個名稱下載到本地'''
# url = 'http://img14.360buyimg.com/n1/s450x450_jfs/t1/148801/37/12770/118749/5f9d71e4E39f1e893/533675187c108953.jpg'
reponse = requests.get(url)
# name = 'd:/photo.jpg'
with open(name, 'wb') as ft:
ft.write(reponse.content)
def drop_scroll(browser):
'''將滑條從頭滾動到底,以便讓瀏覽器充分加載'''
for x in range(1, 11, 2):
# time.sleep(0.5)
j = x/10
js = 'document.documentElement.scrollTop = document.documentElement.scrollHeight * %f' % j
browser.execute_script(js)
def switch_window(browser):
'''將browser的指令移到新打開的小窗口處'''
# time.sleep(0.5) # 如果移轉失敗,請增大這個時間
windows = browser.window_handles
browser.switch_to.window(windows[-1])
def switch_window_back(browser):
'''將browser的指令移回舊的小窗口'''
windows = browser.window_handles
browser.switch_to.window(windows[0])
# 構造網址
u_id= input('請輸入https://www.zhihu.com/people/{u_id}中的u_id')
url = f'https://www.zhihu.com/people/{u_id}'
page = int(input("要遍歷的頁數(從第一頁開始)"))
# 打開知乎
chrome_options = Options()
chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222") # 前面設置的端口號
browser = webdriver.Chrome(options=chrome_options)
# browser.set_window_size(900, 500) # 設置窗口大小
# browser.set_window_position(300, 200) # 設置瀏覽器的位置
browser.get(url)
btn=browser.find_element_by_xpath("//button[@aria-label='關閉']")
browser.execute_script("arguments[0].click();", btn)
time.sleep(2)
# 遍歷頁面中每篇回答
count = 1 # 回答的編號
for page_id in range(1,page+1):
# 翻頁
print("Page:%d" %page_id)
url = f'https://www.zhihu.com/people/{u_id}/answers/by_votes/?page={page_id}'
browser.get(url)
time.sleep(2)
btn = browser.find_element_by_xpath("//button[@aria-label='關閉']")
browser.execute_script("arguments[0].click();", btn)
time.sleep(2)
switch_window_back(browser) # 將browser的指令移回到新標簽頁
drop_scroll(browser) #滑條拖到底,讓加載完全
answers = browser.find_elements_by_xpath("//div[@class='ContentItem AnswerItem']") # 獲取所有回答
for answer in answers:
print(answer.find_element_by_xpath(".//a[@data-za-detail-view-element_name='Title']").get_attribute('href')\
, answer.find_element_by_xpath(".//a[@data-za-detail-view-element_name='Title']").text\
, answer.find_element_by_xpath(".//button[@class='Button VoteButton VoteButton--up']").text
, sep=' , ')
print(count)
count=count+1
一個注意的點是webdriver.Chrome()是可以傳入參數的,
executable_path傳入的值得當的話不必把chromedriver.exe設在$PATH里
//以上圖片來自這個網站
像極了一名爬蟲新手的課程作業。。。
爬取了85頁之后被知乎檢測到了。。。