- 应用模块
- 数据提取方式pyquery解析库
- 网页分析
仅供学习参考错误之处还请留言交流。
方法与思路
应用模块
from selenium import webdriver #导入驱动webdriver from selenium.webdriver.common.by import By #By是selenium中内置的一个class在这个class中有各种方法来定位元素 from selenium.webdriver.support.ui import WebDriverWait #设置浏览器驱动休眠等待避免频繁操作封ip from selenium.webdriver.support import expected_conditions as EC #判断一个元素是否存在如何判断alert弹窗出来了如何判断动态的元素等等一系列的判断在selenium的expected_conditions模块收集了一系列的场景判断方法 from time import sleep #休息睡眠 from pyquery import PyQuery as pq #pyquery是个解析库 pyquery对象初始化html字符串urlfile皆可
数据提取方式pyquery解析库
html browser.page_sourcedoc pq(html)items doc(#J_goodsList .gl-warp.clearfix .gl-item).items()for index, i in enumerate(items):if i(.p-img a).attr(href)[0] /:ss http: i(.p-img a).attr(href)else:ss i(.p-img a).attr(href)product {index: index,price: i(p-price i).text(),name: i(.p-shop a).text(),commit: i(.p-commit a).text(),# img: i(.p-mig img).attr(src)}
网页分析
本案例选用的是CSS_SELECTOR选择元素关键之处就是找准参考元素的位置如按照代码从上到下顺序 #key商品搜索输入栏。 #search > div > div.form > button商品搜索确认按钮 #J_bottomPage > span.p-num > a.curr页数高亮即当前所在页 #J_bottomPage > span.p-skip > em:nth-child(1) > b商品总页数 #J_goodsList > ul > li:last-child页面商品中的最后一个商品 #J_goodsList .gl-warp.clearfix .gl-item页面中60个商品每个商品 #J_bottomPage > span.p-skip > input页数跳转输入栏 #J_bottomPage > span.p-skip > a页数跳转确认按钮 #J_bottomPage > span.p-num > a.curr页数高亮即当前所在页 搜索框的#key 首先鼠标放至页面搜索框右击检查则跳转到搜索框对应代码在选中的代码上右击点击Copy,Copy selector那么复制下来的就是我们需要的 #key 了。 获取图示
代码如下
# encoding: utf-8# time: 2020/3/23 16:11from selenium import webdriverfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.support.ui import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as ECfrom time import sleepfrom pyquery import PyQuery as pq#browser:浏览器将浏览器设置为谷歌驱动# 这里需要下载谷歌对应的驱动,使用火狐浏览器安装驱动后webdriver.Firefox()browser webdriver.Chrome()#转到目标网站browser.get(http://www.jd.com/)#浏览器等待10秒wait WebDriverWait(browser, 10)KEY 泡面def search():#解决加载超时出错try:#input输入框等待加载出元素#key#key是在搜索输入框对应的代码右击Copy,Copy selector复制粘贴下来input wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, #key)))#submit按钮即搜索确认按钮#search > div > div.form > button获取方式同理submit wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, #search > div > div.form > button)))#输入框输入键即字输入内容为KEYinput.send_keys(KEY)#确认按钮点击submit.click()#睡眠延迟2秒避免频繁操作封IPsleep(2)#等待加载出底部页面信息第一页,EC.text_to_be_present_in_element为判断元素上有文本信息##J_bottomPage > span.p-num > a.currcurr为页寄存器一般高亮显示处为所在页数wait.until(EC.text_to_be_present_in_element((By.CSS_SELECTOR, #J_bottomPage > span.p-num > a.curr), 1))sleep(2)#执行函数获取商品信息get_products()#获取商品页数total wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, #J_bottomPage > span.p-skip > em:nth-child(1) > b)))#print(total)#返回# print(total.text)#返回100return total.text#超时出错时重新执行search()程序except TimeoutError:return search()#获取商品信息def get_products():##J_goodsList > ul > li:nth-child(60)为页末最后一个商品信息最后一个商品信息加载出来则全页商品信息全部加载出来wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, #J_goodsList > ul > li:last-child)))#获取网页源码html browser.page_source# print(html)# 解析doc pq(html)# print(doc)#J_goodsList .gl-warp.clearfix .gl-item为idJ_goodsList标签下classgl-warp.clearfix# 的子标签下的classgl-item的标签即每页60个商品标签有60个结果items doc(#J_goodsList .gl-warp.clearfix .gl-item).items()#enumerate()枚举、列举、计算for index, i in enumerate(items):# print(i(.p-name.p-name-type-2 em).text())# print(*30)# 运行结果# 康师傅方便面 Express速达面馆煮面 私房红烧牛肉面*2金牌香辣牛肉面*2 袋装# 泡面# 礼盒整箱装# # 京东超市统一 方便面 来一桶 老坛酸菜牛肉面辣味 12桶 整箱装# if i(.p-img a).attr(href)[0] /:ss http: i(.p-img a).attr(href)else:ss i(.p-img a).attr(href)product {index: index,price: i(.p-price i).text(),name: i(.p-shop a).text(),commit: i(.p-commit a).text(),# img: i(.p-mig img).attr(src)}print(product)#运行结果图片爬取失败# {index: 0, price: , name: 统一京东自营旗舰店, commit: 23万, img: None}# {index: 1, price: , name: 康师傅方便面京东自营官方旗舰店, commit: 27万, img: None}def next_page(page_num):print(-------------------------------正在翻页-------------------------------)sleep(2)try:#由于京东页面并不是一次性加载出来所以可以通过下拉条下拉模拟浏览刷新未展示商品browser.execute_script(window.scrollTo(0, 0.8*document.body.scrollHeight))sleep(1)#input为底部页面转换输入框input wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, #J_bottomPage > span.p-skip > input)))#submit为底部页面转换跳转确定按钮submit wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, #J_bottomPage > span.p-skip > a)))#清空输入框input.clear()#输入框中输入页数input.send_keys(page_num)#确认跳转submit.click()#直到加载出page_num所在页为高亮即确认跳转成功wait.until(EC.text_to_be_present_in_element((By.CSS_SELECTOR, #J_bottomPage > span.p-num > a.curr), str(page_num)))sleep(1)#执行函数获取跳转页面的商品信息get_products()except TimeoutError:return next_page(page_num)def main():total search()# get_products()#搜索商品过后便是商品搜索结果的第一页翻页无需跳转第一页从第二页开始#int(total)1total的值是个字符串int()转换为数值range()管前不管后所以1for i in range(2, int(total)1):next_page(i)if __name__ __main__:main()