好久没看爬虫的相关的内容了,趁着有时间水一篇博客~
任务:使用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()
运行截图~