好久沒看爬蟲的相關的內容了,趁着有時間水一篇博客~
任務:使用selenium爬取京東上狗糧相關信息
準備工作:除了selenium安裝外,還需要安裝對應瀏覽器的Driver,我是在Chrome瀏覽器上測試的(安裝ChromeDriver的時候需要注意Driver的版本與Chrome的版本需要一致)
Selenium測試直接運行在瀏覽器中,就像真正的用戶在操作一樣。支持的瀏覽器包括IE(7, 8, 9, 10, 11),Firefox,Safari,Chrome,Opera等。使用python爬蟲調用selenium來模擬正常用戶訪問瀏覽器。可以省去好多抓包解碼的過程了~
總體上爬蟲還是分爲三步:獲取網頁、爬取數據。數據存儲。
獲取網頁
進入京東主頁後,在這一頁需要做的輸入“狗糧”關鍵詞,並點擊搜素按鈕。需要做的即查看這兩個元素對應的標籤,使用find_element_by_XXX即可,找到後執行相關操作。
點擊搜索後,發現每一頁的商品並不是初始就全部加載完成的,我們需要先滑動頁面至最底部,然後爬取需要信息後,點擊下一頁,點擊下一頁的思路與上面類似。
from selenium import webdriver
import time
from selenium.webdriver.support.wait import WebDriverWait
browser = webdriver.Chrome()
KeyWord = "狗糧" #搜索關鍵詞
wait = WebDriverWait(browser, 10) #等待條件
def get_html():
url = "https://www.jd.com/"
browser.get(url)
input = browser.find_element_by_id('key') #找到輸入關鍵詞的地方
input.send_keys(KeyWord) #輸入關鍵詞
time.sleep(1)
button = browser.find_element_by_class_name('button') #找到確定搜索的按鈕
button.click() #點擊後會進入第一頁
time.sleep(1)
for i in range(1, 101):
print("正在爬取第%d頁"%i)
browser.execute_script('window.scrollTo(0, document.body.scrollHeight)') #將頁面滑到底部,加載該頁面的剩餘商品
time.sleep(1)
if i != 100:
next_button = browser.find_element_by_class_name('pn-next') #找到下一頁的按鈕
next_button.click() #點擊進入下一頁
time.sleep(1)
爬取數據
這一步主要是繁瑣~,對着商品頁的源碼,使用xpath或者其他工具,處理一下,得到我們需要的數據即可。
titles = ["names", "price","store","comments"] #title
values = [] #存放爬取信息
def get_products():
html = browser.page_source
htmlElement = etree.HTML(html)
products = htmlElement.xpath(".//ul[@class='gl-warp clearfix']/li")
for product in products:
name = product.xpath(".//div[@class='p-name p-name-type-2']//i/text()")
if len(name) == 0:
name = etree.tostring(product.xpath(".//div[@class='p-name p-name-type-2']//em")[0]).decode('utf-8')
name = re.sub('<.*?>', '',name)
else:
name = name[0]
name = re.sub('\n', ' ', name)
price = product.xpath(".//div[@class='p-price']//em/text()")+product.xpath(".//div[@class='p-price']//i/text()")
store = product.xpath(".//div[@class='p-shop']//a/text()")
comment = product.xpath(".//div[@class='p-commit']//a/text()")
values.append([name, price[0]+price[1], store[0], comment[0]])
print([name, price[0]+price[1], store[0], comment[0]])
數據存儲
將得到的數據存儲爲csv文件
filepath = "./products.csv" #文件存放地址
def save_products():
with open(filepath, 'w', encoding='utf-8', newline='') as fp:
writer = csv.writer(fp)
writer.writerow(titles) # 寫標題
writer.writerows(values)
完整代碼
from selenium import webdriver
import time
from selenium.webdriver.support.wait import WebDriverWait
from lxml import etree
import csv
import re
browser = webdriver.Chrome()
KeyWord = "狗糧" #搜索關鍵詞
wait = WebDriverWait(browser, 10) #等待條件
filepath = "./products.csv" #文件存放地址
titles = ["names", "price","store","comments"] #title
values = [] #存放爬取信息
def get_html():
url = "https://www.jd.com/"
browser.get(url)
input = browser.find_element_by_id('key') #找到輸入關鍵詞的地方
input.send_keys(KeyWord) #輸入關鍵詞
time.sleep(1)
button = browser.find_element_by_class_name('button') #找到確定搜索的按鈕
button.click() #點擊後會進入第一頁
time.sleep(1)
for i in range(1, 101):
print("正在爬取第%d頁"%i)
browser.execute_script('window.scrollTo(0, document.body.scrollHeight)') #將頁面滑到底部,加載該頁面的剩餘商品
get_products() #爬取該頁面的商品
time.sleep(1)
if i != 100:
next_button = browser.find_element_by_class_name('pn-next') #找到下一頁的按鈕
next_button.click() #點擊進入下一頁
time.sleep(1)
def get_products():
html = browser.page_source
htmlElement = etree.HTML(html)
products = htmlElement.xpath(".//ul[@class='gl-warp clearfix']/li")
for product in products:
name = product.xpath(".//div[@class='p-name p-name-type-2']//i/text()")
if len(name) == 0:
name = etree.tostring(product.xpath(".//div[@class='p-name p-name-type-2']//em")[0]).decode('utf-8')
name = re.sub('<.*?>', '',name)
else:
name = name[0]
name = re.sub('\n', ' ', name)
price = product.xpath(".//div[@class='p-price']//em/text()")+product.xpath(".//div[@class='p-price']//i/text()")
store = product.xpath(".//div[@class='p-shop']//a/text()")
comment = product.xpath(".//div[@class='p-commit']//a/text()")
values.append([name, price[0]+price[1], store[0], comment[0]])
print([name, price[0]+price[1], store[0], comment[0]])
def save_products():
with open(filepath, 'w', encoding='utf-8', newline='') as fp:
writer = csv.writer(fp)
writer.writerow(titles) # 寫標題
writer.writerows(values)
get_html()
save_products()
運行截圖~