記錄一下最近一次爬蟲的場景和應(yīng)用育韩,很久沒有寫了,而且之前的腳本也不好找了赤屋。
爬蟲場景:需要用戶登錄系統(tǒng)壁袄,輸入用戶的賬號和密碼進(jìn)入系統(tǒng)变泄,進(jìn)入系統(tǒng)頁面后,在chrome瀏覽器可以查看到蛙卤,前端頁面展示的數(shù)據(jù)是通過ajax請求后端服務(wù)器的數(shù)據(jù)。
策略:如果不需要登錄系統(tǒng)垛耳,爬蟲很好實現(xiàn)堂鲜。
我想到的有兩種方法缔莲,第一種方法手動抛虫,比較笨拙,如果數(shù)據(jù)量不是很多棉姐,也夠用伞矩。
現(xiàn)在很多網(wǎng)站都使用Ajax作為數(shù)據(jù)接口沟蔑,這樣其實也方便爬蟲爬取數(shù)據(jù)厅须。
chrome瀏覽器按F12鍵眶拉,調(diào)出開發(fā)者工具镰禾,切換到“Network”,選擇篩選XHR資源劫樟。當(dāng)我們點擊關(guān)注的某些頁面叠艳,會向后端服務(wù)器發(fā)送請求返回ajax文件附较,該ajax文件里面包含我們需要爬取的信息吃粒。
點擊紅色框的下載按鈕,保存har文件拒课。下次可以點擊旁邊的上傳按鈕徐勃,上傳har文件。另外早像,也有一些插件可以輔助har文件瀏覽僻肖。
第二種方法是Selenium+chrome driver 實現(xiàn)模擬登陸,使用 Selenium 獲取 ajax (xhr) 數(shù)據(jù)卢鹦,注意到url是動態(tài)生成的臀脏,簡單的通過requests的post或get方法不易實現(xiàn)。
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import os, time, json
from selenium.webdriver.common.by import By
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
if __name__ == '__main__':
# 引入chromedriver
chrome_options = webdriver.ChromeOptions()
# chrome_options.add_argument('--headless')
# chrome_options.add_argument('--no-sandbox')
# chrome_options.add_argument("--disable-extensions")
# chrome_options.add_argument("--disable-gpu")
prefs = {
'download.default_directory': os.getenv('OS_LOG_PATH')
}
chrome_options.add_experimental_option('prefs', prefs)
# make chrome log requests
capabilities = DesiredCapabilities.CHROME
# caps['goog:loggingPrefs']
capabilities["goog:loggingPrefs"] = {"performance": "ALL"} # newer: goog:loggingPrefs
# capabilities['acceptSslCerts'] = True
#browser = webdriver.Chrome(executable_path=r'/opt/google/chrome/chromedriver', options=chrome_options)
browser = webdriver.Chrome(executable_path=r'C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe', options=chrome_options,desired_capabilities=capabilities)
browser.implicitly_wait(3)
browser.get("https://#########")
# 輸入賬號
browser.implicitly_wait(3)
username_inputbox = browser.find_elements(By.XPATH, '//*[@id="app"]/section/div[1]/div/div[1]/div/div[2]/form/div[1]/div/div/div/input')[0]
username_inputbox.click()
browser.implicitly_wait(3)
username_inputbox.clear()
username_inputbox.send_keys("#######")
# 輸入密碼
browser.implicitly_wait(3)
password_inputbox = browser.find_elements(By.XPATH, '//*[@id="app"]/section/div[1]/div/div[1]/div/div[2]/form/div[2]/div/div/div/input')[0]
password_inputbox.click()
browser.implicitly_wait(3)
password_inputbox.clear()
password_inputbox.send_keys("#######")
# 點擊登錄
browser.implicitly_wait(3)
submit_btn = browser.find_elements(By.XPATH, '//*[@id="app"]/section/div[1]/div/div[1]/div/div[2]/form/div[3]/div/button')[0]
submit_btn.click()
# 等待5秒
time.sleep(5)
#-------------------------------------------------
base_url = "https://#########"
browser.get(base_url)
time.sleep(3)
# extract requests from logs
logs_raw = browser.get_log("performance")
logs = [json.loads(lr["message"])["message"] for lr in logs_raw]
def log_filter(log_):
return (
# is an actual response
log_["method"] == "Network.responseReceived"
# and json
and "json" in log_["params"]["response"]["mimeType"]
)
for log in filter(log_filter, logs):
request_id = log["params"]["requestId"]
resp_url = log["params"]["response"]["url"]
print(request_id)
print(f"Caught {resp_url}")
json_str = json.dumps(browser.execute_cdp_cmd("Network.getResponseBody", {"requestId": request_id}), indent=4)
# 創(chuàng)建一個params.json文件
with open(f'{request_id}.json', 'w') as f:
f.write(json_str) # 將json_str寫到文件中
browser.quit()
下載生成每個json文件
參考鏈接:
1.https://qiita.com/hatobeam75/items/dbe45324c368eedd4460