当前位置 博文首页 > 孤寒者的博客:使用selenium爬取天猫商品
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.keys import Keys
from pyquery import PyQuery as pq
import time
browser = webdriver.Chrome()
# 等待的使用——使用WebDriverWait对象,指定最长等待时间为10S。
wait = WebDriverWait(browser, 10)
KEYWORD = 'iPad'
def login_tianmao():
"""
扫码登录天猫,运行之后会自动打开登录二维码界面并等待,你只需拿起手机扫码登录即可!
:return:
"""
url = 'https://login.tmall.com/'
browser.get(url)
browser.maximize_window()
# 因为二维码界面在嵌套的iframe框架中,所以先跳转进入该iframe
browser.switch_to.frame('J_loginIframe')
# 点击出现登录二维码
browser.find_element_by_class_name('icon-qrcode').click()
time.sleep(6)
# 显示等待——如果在上面设置的最长等待时间10S内成功匹配了等待条件,也就是说页面元素成功加载出来了,就立即返回相应结果并继续向下执行
# 否则到了最大等待时间还没有加载出来时,就直接抛出超时异常!
# 此处等待条件为判断天猫是否登录成功——如果登录成功会出现搜索框!
input = wait.until(
EC.presence_of_element_located((By.CLASS_NAME, 's-combobox-input'))
)
# 输入搜索关键字
input.send_keys(KEYWORD)
time.sleep(1)
# 使用Keys的ENTER,相当于.click()函数
input.send_keys(Keys.ENTER)
def index_page(page):
"""
抓取索引页
:param page:页码
:return:
"""
print("正在爬取第", page , "页")
try:
if page == 1:
login_tianmao()
else:
# selenium执行JS代码,下滑操作——使页面下滑至出现页码输入框,便于观察!
js = 'scrollTo(0,4200)' # js语句
browser.execute_script(js) # 执行js的方法
# 显示等待——等待条件:定位到跳转页码输入框!
input = wait.until(
EC.presence_of_element_located((By.CLASS_NAME, 'ui-page-skipTo'))
)
# 显示等待——等待条件:定位到可点击的页码跳转确定按钮!
submit = wait.until(
EC.element_to_be_clickable((By.CLASS_NAME, 'ui-btn-s'))
)
# 清空输入框,输入下一页的页码,点击!
input.clear()
input.send_keys(page)
submit.click()
# 如果判断有没有跳转到对应的页码——观察可知只需判断当前高亮的页码数是当前的页码数即可!!!
# 显示等待——等待条件:检测当前高亮的页码节点是不是我们传过来的页码数,如果是就证明页面成功跳转到了这一页!
# .text_to_be_present_in_element()——它会等待指定的文本出现在某一个节点里面时即返回成功!
wait.until(
EC.text_to_be_present_in_element((By.CSS_SELECTOR, '.ui-page .ui-page-wrap .ui-page-num .ui-page-cur'),
str(page))
)
# 显示等待——等待条件:定位到每个商品的信息块!
wait.until(
EC.presence_of_element_located((By.CSS_SELECTOR, '#J_ItemList')))
# 提取商品信息!
get_products()
except TimeoutException:
index_page(page)
def get_products():
"""
提取商品数据 使用pyquery进行解析!
:return:
"""
html = browser.page_source
# 构造PyQuery解析对象
doc = pq(html)
# 提取商品列表,此处匹配到的是整个页面的每个商品,它的匹配结果是多个,所以需要使用.items()方法对它进行遍历
# 调用items()方法后,会得到一个生成器,遍历即可获取每个值。遍历之后的每个值依旧是PyQuery类型。
items = doc('#J_ItemList .product-iWrap').items()
for item in items:
product = {
#商品图片链接
'image': item.find('.productImg-wrap .productImg img').attr('src'),
# 商品价格
'price': item.find('.productPrice').text(),
# 商品成交量
'deal': item.find('.productStatus').text(),
# 商品名称
'title': item.find('.productTitle a').attr('title'),
# 商品店铺
'shop': item.find('.productShop').text(),
}
print(product)
# 写入本地txt
with open('1.txt', 'a+', encoding='utf-8') as f:
f.write(str(product))
f.write('\n')
# 模拟抓取十页!
MAX_PAGE = 10
def main():
for i in range(1, MAX_PAGE + 1):
index_page(i)
browser.quit()
if __name__ == '__main__':
main()