使用Selenium模拟浏览器抓取淘宝商品美食信息(含模拟登陆)
淘宝页面比较复杂,含有各种请求参数和加密参数,如果直接请求或者分析Ajax将会非常繁琐。
Selenium是一个自动化测试工具,可以驱动浏览器去完成各种工作,比如模拟点击、输入和下拉等多种功能,这样我们只需关心操作,
不需要关心后台发生了怎么样的请求下面对具体操作步骤进行详述。
所用到的
- selenium
- pyqurey
- re
- pymongo
数据库截图
实现代码
# -*- coding: utf-8 -*-
"""
@Time : 2021/1/25 17:02
@Auth : Ne-21
@File :taobaospider.py
@IDE :PyCharm
@Motto:Another me.
"""
import re
from selenium.common.exceptions import TimeoutException
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver import ActionChains
import time
from pyquery import PyQuery as pq
import pymongo
# Mongo数据库
MONGO_URL = 'localhost'
MONGO_DB = 'taobao'
MONGO_TABLE = 'product'
client = pymongo.MongoClient(MONGO_URL)
db = client[MONGO_DB]
options = webdriver.ChromeOptions()
# options.add_argument('--blink-settings=imagesEnabled=false') # 不加载图片, 提升速度
# options.add_argument('--headless') # 浏览器不提供可视化页面
browser = webdriver.Chrome(options=options)
# 防止被监测
browser.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
"source": '''
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
})
'''
})
wait = WebDriverWait(browser, 5)
def do_slider():
"""
处理滑动验证码,没有测试
:return:
"""
slider_go = wait.until(
EC.presence_of_element_located((By.CSS_SELECTOR, '#nc_1_n1z'))
)
# 实例化一个动作链关联游览器
action = ActionChains(browser)
action.reset_actions()
# 使用鼠标动作链进行点击并悬浮
action.click_and_hold(slider_go)
# 滑动验证码
action.move_by_offset(xoffset=258, yoffset=0).perform()
time.sleep(5)
def login(username, password):
print('正在登陆......')
browser.get('https://login.taobao.com/member/login.jhtml')
input_username = wait.until(
EC.presence_of_element_located((By.CSS_SELECTOR, '#fm-login-id'))
)
input_password = wait.until(
EC.presence_of_element_located((By.CSS_SELECTOR, '#fm-login-password'))
)
submit = wait.until(
EC.element_to_be_clickable((By.CSS_SELECTOR, '#login-form > div.fm-btn > button'))
)
input_username.send_keys(username)
time.sleep(2)
input_password.send_keys(password)
time.sleep(2)
submit.click()
time.sleep(3) # 等待检验滑块
# 判断有无滑块验证
try:
slider = wait.until(
EC.presence_of_element_located((By.CSS_SELECTOR, '#nc_1__scale_text > span'))
)
if bool(slider):
print('发现滑块验证码')
do_slider()
submit.click()
else:
print('未发现滑块')
pass
except:
print('未发现滑块')
time.sleep(5) # 等待短信验证
# 判断有无短信验证
try:
# 定位iframe标签,由于iframe没有id,name这种唯一的属性,因此只能通过先定位,在切换实现
frame = wait.until(
EC.presence_of_element_located((By.XPATH, '//*[@id="content"]/div/div[1]/iframe'))
)
# 由于手机验证页面出现了页面的嵌套,因此需要进行页面跳转到iframe下
browser.switch_to.frame(frame)
sms_button = wait.until(
EC.presence_of_element_located((By.XPATH, '//*[@id="J_GetCode"]'))
)
if bool(sms_button):
print('发现短信验证码')
time.sleep(1)
sms_button.click()
print('验证码已发送,请输入验证码(20s)')
time.sleep(20)
sms_submit = wait.until(
EC.element_to_be_clickable((By.CSS_SELECTOR, '#submitBtn'))
)
sms_submit.click()
else:
print('无短信验证')
pass
except:
print('无短信验证...')
pass
finally:
print('登陆成功')
def search():
print('正在搜索.....')
try:
browser.get('https://www.taobao.com')
# 等待目标元素加载完成
# input = WebDriverWait(browser, 10).until(
# EC.presence_of_all_elements_located(By.CSS_SELECTOR, '#q')
# )
# submit = WebDriverWait(browser, 10).until(
# EC.element_to_be_clickable(By.CSS_SELECTOR, '#J_TSearchForm > div.search-button > button')
# )
# 改写WebDriverWait
input = wait.until(
EC.presence_of_element_located((By.CSS_SELECTOR, '#q'))
)
submit = wait.until(
EC.element_to_be_clickable((By.CSS_SELECTOR, '#J_TSearchForm > div.search-button > button'))
)
# 输入内容
input.send_keys('美食')
submit.click()
# 获取总页数
total = wait.until(
EC.presence_of_element_located((By.CSS_SELECTOR, '#mainsrp-pager > div > div > div > div.total')))
# 第一页解析网页
get_products()
return total.text
except TimeoutException:
return search()
# 翻页操作
def next_page(page_number):
print('正在翻页......')
try:
# 到第几页
input = wait.until(
EC.presence_of_element_located((By.CSS_SELECTOR, '#mainsrp-pager > div > div > div > div.form > input'))
)
# 确定按钮
submit = wait.until(
EC.element_to_be_clickable(
(By.CSS_SELECTOR, '#mainsrp-pager > div > div > div > div.form > span.btn.J_Submit'))
)
input.clear()
input.send_keys(page_number)
submit.click()
# 判断是否已翻到指定页面(*)
wait.until(EC.text_to_be_present_in_element(
(By.CSS_SELECTOR, '#mainsrp-pager > div > div > div > ul > li.item.active > span'), str(page_number)))
# 翻页后解析网页
get_products()
except TimeoutException:
return next_page(page_number)
# 解析网页
def get_products():
# 商品信息是否存在
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '#mainsrp-itemlist .items .item')))
# 拿到网页源代码
html = browser.page_source
# pyquery解析
doc = pq(html)
items = doc('#mainsrp-itemlist .items .item').items()
for item in items:
product = {
'image': item.find('.pic .img').attr('src'),
'price': item.find('.price').text(),
'deal': item.find('.deal-cnt').text()[:-3],
'title': item.find('.title').text(),
'shop': item.find('.shop').text(),
'location': item.find('.location').text()
}
print(product)
save_to_mongo(product)
def save_to_mongo(result):
print('正在加入数据库......')
try:
if db[MONGO_TABLE].insert(result):
print('存储到MONGODB成功', result)
except Exception:
print('存储异常', result)
def main():
print('开始运行.......')
login('', '')
total = search()
total = int(re.compile('(\d+)').search(total).group(1))
for i in range(2, total + 1):
next_page(i)
browser.close()
if __name__ == '__main__':
main()
补充
chrome_options.add_argument('--user-agent=""') # 设置请求头的User-Agent
chrome_options.add_argument('--window-size=1280x1024') # 设置浏览器分辨率(窗口大小)
chrome_options.add_argument('--start-maximized') # 最大化运行(全屏窗口),不设置,取元素会报错
chrome_options.add_argument('--disable-infobars') # 禁用浏览器正在被自动化程序控制的提示
chrome_options.add_argument('--incognito') # 隐身模式(无痕模式)
chrome_options.add_argument('--hide-scrollbars') # 隐藏滚动条, 应对一些特殊页面
chrome_options.add_argument('--disable-javascript') # 禁用javascript
chrome_options.add_argument('--blink-settings=imagesEnabled=false') # 不加载图片, 提升速度
chrome_options.add_argument('--headless') # 浏览器不提供可视化页面
chrome_options.add_argument('--ignore-certificate-errors') # 禁用扩展插件并实现窗口最大化
chrome_options.add_argument('--disable-gpu') # 禁用GPU加速
chrome_options.add_argument('–disable-software-rasterizer')
chrome_options.add_argument('--disable-extensions')
chrome_options.add_argument('--start-maximized')
版权声明:
作者:Ne-21
链接:https://blog.gocos.cn/archives/62.html
来源:云淡风轻
文章版权归作者所有,未经允许请勿转载。
THE END
0
二维码
海报
使用Selenium模拟浏览器抓取淘宝商品美食信息(含模拟登陆)
淘宝页面比较复杂,含有各种请求参数和加密参数,如果直接请求或者分析Ajax将会非常繁琐。
Selenium是一个自动化测试工具,可以驱动浏览器去完成各种工作,比……

共有 0 条评论