大家好,我是 zeroing~
今天介紹一下如何用 Python 來爬取京東商品類目,數據包含商品標題、價格、出版社、作者等信息,
本次爬蟲用到的核心庫為 Selenium + pyquery ,Selenium 用於驅動瀏覽器對網頁進行模擬訪問,pyquery 用於解析頁面信息做數據提取,先看一下最終效果
啟動腳本之后,Selenium 自動打開頁面京東網頁端頁面,對商品頁信息進行翻頁操作,在瀏覽器翻頁的同時,控制后台返回提取到的數據,
在介紹主程序之前,這里先介紹 Selenium 程序包
Selenium 的安裝
Selenium 主要作為 Web 應用程序的測試工具,能夠操控瀏覽器完成一系列步驟,模擬人為操作;比如自動刷課
,自動填寫文本
,網頁端自動查詢快遞單號
都是沒問題的,目前支持 Java、Python、C#、Ruby 等多種語言;
在做網頁爬取時,有的網頁的數據是以 Ajax 方式進行渲染,如微博,頭條沒有下一頁入口通過刷新頁面實現翻頁效果;這類網頁端數據並不是直接放在 html 中,是通過用戶操作觸發鑲嵌在html 中的 js 命令,從而調用存放 json 文件中的數據,最終呈現;
對於這類網頁采集時,一般有兩種思路:
- 1,利用開發者工具,找到存放 json 數據隱藏鏈接,再用常規的 Request 方法對數據進行提取;
- 2,利用 Selenium 工具模擬人為操作,實現數據的抓取;
因此 Selenium 工具可以對於網頁端的一些反爬措施能夠達到一些有效的抑制;
Python 使用 Selenium 時可以借助封裝好的 Selenium 庫,安裝時利用 pip 命令即可完成
pip install selenium
目前 Selenium 支持的瀏覽器包括 Chrome 和 Firefox ,這里建議大家選擇 Chrome 會好一點,因為網上關於 Chrome 的文檔相對會多一點,
但在使用之前,除了保證 Chrome 瀏覽器安裝好之外,還需要確保 chromedriver.exe 工具( Selenium 的核心為 webdriver,而 chromedriver.exe 為 Chrome 的 WebDriver 工具)也安裝好
chromedriver 的版本需要與 Chrome 瀏覽器的版本對應,下載到本地即可
下載地址如下:https://chromedriver.chromium.org/downloads
2,爬蟲邏輯
用 Selenium 模擬人為操作對京東數據進行抓取,緊要依次進行以下幾個步驟(這里以抓取 Python書籍 商品為例):
- 1,驅動瀏覽器,打開京東網站;
- 2,找到搜素框,清空並填入關鍵詞Python書籍,再點擊一下旁邊的搜索按鈕;
- 3,轉到商品頁對數據進行抓取,再驅動 Selenium 工具完成翻頁操作,依次對全部數據進行抓取;
首先需要進行初始化,創建 webdriver 的 Chrome瀏覽器、數據的存儲文件(這里我用的是 txt 文件)
def __init__(self,item_name,txt_path):
url = 'https://www.jd.com/' # 登錄網址
self.url = url
self.item_name = item_name
self.txt_file = open(txt_path,encoding='utf-8',mode='w+')
options = webdriver.ChromeOptions() # 谷歌選項
# 設置為開發者模式,避免被識別
options.add_experimental_option('excludeSwitches',
['enable-automation'])
self.browser = webdriver.Chrome(executable_path= "C:/Program Files/Google/Chrome/Application/chromedriver.exe",
options = options)
self.wait = WebDriverWait(self.browser,2)
webdriver.Chrome() 方法用於創建一個驅動的瀏覽器 Chrome ,將之前下載到本地的 chromedriver.exe 文件夾路徑賦給 executable_path 參數,
在瀏覽器打開網頁時,可能由於網速出現加載慢的問題,因此這里用 WebDriverWait 方法來創建一個 wait 方法,每次調用時瀏覽器都需要等待 2 秒之后再進行下一步操作;
初始化操作之后,接下來就是主程序進行模擬訪問、輸入、點擊等操作;我把這部分操作全部封裝到一個 run() 函數中,
def run(self):
"""登陸接口"""
self.browser.get(self.url)
input_edit = self.browser.find_element(By.CSS_SELECTOR,'#key')
input_edit.clear()
input_edit.send_keys(self.item_name)
search_button = self.browser.find_element(By.CSS_SELECTOR,'#search > div > div.form > button')
search_button.click()# 點擊
time.sleep(2)
html = self.browser.page_source # 獲取 html
self.parse_html(html)
current_url = self.browser.current_url # 獲取當前頁面 url
initial_url = str(current_url).split('&pvid')[0]
for i in range(1,100):
try:
print('正在解析----------------{}圖片'.format(str(i)))
next_page_url = initial_url + '&page={}&s={}&click=0'.format(str(i*2+1),str(i*60+1))
print(next_page_url)
self.browser.get(next_page_url)
self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'#J_goodsList > ul > li')))
html = self.browser.page_source
self.parse_html(html)# 對 html 網址進行解析
time.sleep(2) # 設置頻率
except Exception as e:
print('Error Next page',e)
self.txt_file.close()# 關閉 txt 文件
首先用 get() 方法訪問京東主頁面,再定位到頁面中的搜索欄和搜索按鈕標簽 input_edit
、search_button
;完成輸入,點擊操作
關於網頁元素標簽定位,如果不會的話可借助於瀏覽器開發者模式,分為下面幾步(這里以 CSS_Selector 為例):
- 1,點擊開發者模式中左上角拾取元素按鈕;
- 2,用鼠標點擊你要選擇的元素;
- 3,在 html 源碼選中區域,鼠標右鍵選擇 Copy
- 4,選中 Copy Selector 選項;
- 5,粘貼到粘貼板上即可;
在進行翻頁操作時,這里根據 京東 url 規律來進行構造的,
第 5 頁
https://search.jd.com/Search?keyword=%E4%BB%A3%E6%A3%AE%E9%93%B5&qrst=1&suggest=7.def.0.base&wq=%E4%BB%A3%E6%A3%AE%E9%93%B5&stock=1&page=9&s=241&click=0
第 6 頁
https://search.jd.com/Search?keyword=%E4%BB%A3%E6%A3%AE%E9%93%B5&qrst=1&suggest=7.def.0.base&wq=%E4%BB%A3%E6%A3%AE%E9%93%B5&stock=1&page=11&s=301&click=0
仔細查看的話會發現,這里第 5 頁和第 6 頁 url 唯一不同的就是其中兩個參數 page
和 s
;
-
page
之間相差2; -
s
之間相差 60;
根據這個規律,通過更改 page 和 s 參數來構建京東商品前100 頁商品信息,來完成數據的抓取;
關於數據提取部分,我利用 parse_html
函數來完成
為了提高程序的友好性,我把全部功能封裝到一個類中,使用者只需要輸入兩個參數,一個是用於需要采集的商品名稱,另一個是存儲文件路徑;即可完成數據的爬取;
最終把爬取到的數據存入 txt 文件中,結果如下
4,總結
盡管 selenium 對於網頁端的一些反爬機制實現有效地破解,但對於一些網站時沒有用的,例如拉勾網,當你用 Selenium 驅動瀏覽器在拉鈎官網模擬翻頁操作時,網站能識別出非人為操作,對你的 IP 進行暫時性封禁並警告;
關於本篇文章涉及到的完整源碼,關注微信公號:小張Python,后台回復關鍵字:京東商品 ,即可獲取!
好了,以上就是本篇文章的全部內容了,最后感謝大家的閱讀!