代码链接
利用selenium来自动翻页爬取淘宝商品的标题,价格,销量,产地信息。
导入库:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver import Chrome
import time
import json
import pandas as pd
注意自己配置好python环境(谷歌驱动…)
利用selenium,手动登录获取cookie保存在本地用于登录平台(便于测试代码),访问商品页url通过Xpath选中对象拿数据,翻页,通过Xpath选中对象拿数据,翻页,通过Xpath选中对象拿数据…
为什么使用selenium?
ans:
1.可行性:
网页源代码中是没有所需数据的。
在淘宝的关键词搜索页进行页面切换,可以发现浏览器顶部的地址栏url也是没有任何变化,那么就抓包吧,通过开发者工具进行抓包发现所需数据都放在一个js请求的响应中。
在Headers中观察请求发现数据请求地址url(get请求),但是地址中有加密参数要破解,作者暂时还搞不定,不过b站有教哈。(加密参数:sign,t。)
(作者感觉这个t应该就是时间)
注意:
使用selenium时,在搜索后的商品页中需要下拉滚动页面到底部才能获取当前页所有的商品基本展示信息。
原理猜测:商品页中商品展示使用Ajax动态请求,目的是为了可以在不重载网页的条件下,与服务器进行数据交互,更新页面的局部数据。(使用Ajax请求对于流量费的节省和阻碍网络爬虫都有帮助)
在利用selenium进行翻页时,下面这个搜索栏可能会把你的翻页按钮给遮住,导致selenium翻页失败。
怎么办?
用JavaScript模拟点击,这样就无所谓挡不挡住翻页按钮的问题了。
webd.execute_script("arguments[0].click();", element)
有的时候可能触发了反爬机制,新的商品页面代码结构发生变化,让原本的Xpath语句定位不到商品,不过作者控制了爬取速度,重新去爬几次后,还是能避免页面结构发生变化的情况。
最后我在测试代码的时候还发现了一个有趣的现象,大部分时候搜出来的商品页都是40多页没问题,可有那么几次只有11页。(希望知道的朋友可以评论区解答一下哈)
这个代码单独运行一次就好,目的是拿下自己的cookie信息保存在本地,方便后续的代码爬取效果测试不用重复手动登录。
获取cookie
def hq_cookie():
weba = webdriver.Chrome()
weba.maximize_window()
weba.get('https://www.taobao.com/')
weba.delete_all_cookies()
time.sleep(50) #50秒内登录好,根据自己的情况改哈
dictcookies = weba.get_cookies() #拿下cookies 格式为字典
jsoncookies = json.dumps(dictcookies) #字典转json
with open('cookies.txt', 'w') as f:
f.write(jsoncookies) #写入cookies文件
weba.quit()
第一步:通过本地cookie登录后,跳转到关键字搜索页的界面
第二步:开发者分析页面代码结构,写xpath进行对象定位,提取数据(商品标题,价格,销量,产地,页数)
#标题
//div[@class='Title--title--jCOPvpf']
#其他信息
//div[@class='Price--priceWrapper--Q0Dn7pN
def main():
#one-star
web = webdriver.Chrome()
web.maximize_window()
url="https://www.taobao.com/"
web.get(url)
with open('./cookies.txt', 'r') as f:
cookies = f.read()
cookies = json.loads(cookies)
#装载cookie
for cookie in cookies:
if 'expiry' in cookie:
del cookie['expiry']
else:
web.add_cookie(cookie)
web.get(url)
time.sleep(5)
url="https://s.taobao.com/search?commend=all&ie=utf8&initiative_id=tbindexz_20170306&q=FL%20studio&search_type=item&sourceId=tb.index&spm=a21bo.jianhua.201856-taobao-item.2&ssid=s5-e"
web.execute_script(f"window.open('{url}', 'new_window')")
time.sleep(3)
web.switch_to.window(web.window_handles[-1])
# one-end
#滑动页面到底部
for i in range(3):
web.execute_script('window.scrollTo(0,document.body.scrollHeight)')
time.sleep(2)
#xpath定位
obj_tit = web.find_elements(By.XPATH,"//div[@class='Title--title--jCOPvpf']")
obj_jg_xl = web.find_elements(By.XPATH, "//div[@class='Price--priceWrapper--Q0Dn7pN ']")
for i in range(len(obj_tit)):
title=obj_tit[i].text.replace(" ","").strip()
hb=obj_jg_xl[i].find_elements(By.XPATH,".//span")[0].text.strip().replace(" ","")
jgz=obj_jg_xl[i].find_elements(By.XPATH,".//span")[1].text.strip().replace(" ","")
jgx=obj_jg_xl[i].find_elements(By.XPATH,".//span")[2].text.strip().replace(" ","")
fkrs = obj_jg_xl[i].find_elements(By.XPATH, ".//span")[3].text.strip().replace(" ", "")
cd=obj_jg_xl[i].find_elements(By.XPATH, ".//div")
cdd=" "
for i in range(len(cd)):
cdd= cdd+cd[i].text.strip().replace(" ", "")
jg=hb+jgz+jgx
print(title,jg,fkrs,cdd)
titles.append(title)
jgs.append(jg)
fkrss.append(fkrs)
cdds.append(cdd)
#爬取总计页数
k = web.find_element(By.XPATH,"//*[@class='next-pagination-display']")
cs=k.text.split("/")[-1]
print(f"共计{cs}页数据")
#开始爬取多页数据
hqsj(web,int(cs)-1)
相较单页数据爬取就多了一步翻页的操作哈.
def hqsj(web,cs):
for i in range(cs):
an=web.find_element(By.XPATH,"//*[@class='next-icon next-icon-arrow-right next-xs next-btn-icon next-icon-last next-pagination-icon-next']")
web.execute_script("arguments[0].click();", an)
time.sleep(2)
....
按单页爬取的逻辑来就好,(复制粘贴)
if __name__ == '__main__':
titles = []
jgs = []
fkrss = []
cdds = []
main()
data = {'标题': titles, '客单价': jgs, '销量': fkrss, '产地': cdds}
df = pd.DataFrame(data)
df.to_excel('FL销售.xlsx', index=False)