目录
2.3 search_infor_price_from_web 方法
前言
Selenium作为主流的Web自动化测试框架,在数据采集领域也有广泛应用。本文将分享如何使用Selenium实现淘宝物资价格信息的爬取。目前代码还存在一些缺陷,主要体现在:1)未能有效绕过淘宝的反爬虫机制;2)登录环节仍需人工干预。欢迎大伙在评论区分享解决方案。
1 完整代码
import datetime
import os
import time
import pandas as pd
import win32api
import win32con
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
class TaoBao():
# 下载每月出门单信息
def search_infor_price_from_web(self, path_dir=os.path.abspath(r'.'), descr_list=['脱脂纱布', '机器人', '衬衫']):
key1 = win32api.RegOpenKey(win32con.HKEY_CURRENT_USER,
r'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders', 0,
win32con.KEY_READ)
download_path = win32api.RegQueryValueEx(key1, 'Desktop')[0]
download_path = os.path.join(os.path.dirname(download_path), 'Downloads')
print(download_path)
# FileProcess().remove_assign_excel_file_in_path(download_path, key)
# 重新从网站下载调拨文件
print('浏览器设置默认信息,如关闭下载保留提示!!!')
start_x_1 = datetime.datetime.now()
options = Options()
prefs = {'download.prompt_for_download': False, 'download.default_directory': download_path}
options.add_experimental_option("prefs", prefs)
options.add_experimental_option('excludeSwitches', ['enable-automation']) # 这里去掉window.navigator.webdriver的特性
options.add_argument("--disable-blink-features=AutomationControlled")
options.add_argument('--force-device-scale-factor=1')
options.add_argument('--start-maximized') # 最大化窗口
options.add_experimental_option('excludeSwitches', ['enable-automation']) # 禁用自动化栏
options.add_experimental_option('useAutomationExtension',
False) # 禁用自动化栏的原理:将window.navigator.webdriver改为undefined。
# 屏蔽密码提示框
prefs = {
'credentials_enable_service': False, 'profile.password_manager_enabled': False
}
options.add_experimental_option('prefs', prefs)
# 反爬虫特征处理
options.add_argument('--disable-blink-features=AutomationControlled')
# options.add_argument("--headless") # 无界面模式
# options.add_argument("--disadle-gpu") # 禁用显卡
# driver = webdriver.Chrome(chrome_options=options)
driver = webdriver.Chrome(options=options)
# 修改了浏览器的内部属性,跳过了登录的滑动验证
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument",
{"source": """Object.defineProperty(navigator, 'webdriver', {get: () => undefined})"""})
# driver = webdriver.Chrome()
driver.command_executor._commands["send_command"] = ("POST", '/session/$sessionId/chromium/send_command')
params = {'cmd': 'Page.setDownloadBehavior',
'params': {'behavior': 'allow', 'downloadPath': download_path}}
driver.execute("send_command", params)
print('浏览器将打开已经进入!!!')
end_x_1 = datetime.datetime.now()
print('花费%s时长进入浏览器!!!' % (end_x_1 - start_x_1))
driver.maximize_window() # 最大化谷歌浏览器
driver.implicitly_wait(10) # 隐性等待10s
# driver.get('https://www.taobao.com')
driver.get(
'https://login.taobao.com/member/login.jhtml')
# 修改了浏览器的内部属性,跳过了登录的滑动验证
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument",
{"source": """Object.defineProperty(navigator, 'webdriver', {get: () => undefined})"""})
# 手机扫码登入
# 尝试输入密码
try:
time.sleep(3)
# 输入账号密码
username = driver.find_element(By.ID, 'fm-login-id')
# username.send_keys('jianfei.xu')
username.send_keys('XXXXXX')
time.sleep(10)
password = driver.find_element(By.ID, 'fm-login-password')
# password.send_keys('0000000.')
password.send_keys('XXXXX')
time.sleep(10)
# 点击登入
driver.find_element(By.XPATH,
'/html/body/div/div[2]/div[3]/div/div/div/div[1]/div/form/div[6]/button').click()
driver.implicitly_wait(10) # 隐式等待10s
time.sleep(5)
except:
pass
time.sleep(60)
print(123)
data_list = []
for search_str in descr_list:
# 输入搜索框
path = '/html/body/div[3]/div[2]/div[1]/div/div/div[3]/div/div[1]/form/div[4]/input'
driver.find_element(By.XPATH, path).clear()
driver.find_element(By.XPATH, path).send_keys(search_str)
time.sleep(2)
# 查询
path = '/html/body/div[3]/div[2]/div[1]/div/div/div[3]/div/div[1]/form/div[2]/button'
driver.find_element(By.XPATH, path).click()
time.sleep(2)
# 切换浏览器窗口
handle = driver.window_handles # 获取句柄,得到的是一个列表
driver.switch_to.window(handle[-1]) # 切换至最新句柄
time.sleep(10)
try:
path = '/html/body/div[3]/div[3]/div[1]/div[1]/div/div[2]/div[3]'
text_str = driver.find_element(By.XPATH, path).text
except:
pass
try:
path = '/html/body/div[3]/div[3]/div/div[1]/div/div[3]'
text_str = driver.find_element(By.XPATH, path).text
except:
pass
'/html/body/div[3]/div[4]/div/div[1]/div/div[3]/div[3]/div/div[1]/a/div/div[1]/div[1]/img[1]'
'/html/body/div[3]/div[4]/div/div[1]/div/div[3]/div[3]/div/div[2]/a/div/div[1]/div[1]/img'
'/html/body/div[3]/div[4]/div/div[1]/div/div[3]/div[3]/div/div[3]/a/div/div[1]/div[1]/img'
'/html/body/div[3]/div[4]/div/div[1]/div/div[3]/div[3]/div/div[4]/a/div/div[1]/div[1]/img'
# 对text_str进行数据提取
print(text_str)
data_dic = {}
data_dic['物资'] = search_str
text_list = text_str.split('\n')
print(text_list)
ix = 1
for i in range(len(text_list)):
each_str = text_list[i]
if each_str == '¥':
print('>>>>>>>>>>>>>>>>>>>>')
descr_picture_url = os.path.join(path_dir, text_list[i - 1] + '.webp')
print(descr_picture_url)
print(text_list[i - 1]) # 描述
print(text_list[i])
print(text_list[i + 1]) # 金额
print(text_list[i + 3]) # 地点
data_dic['对比%s-描述' % str(ix)] = text_list[i - 1]
data_dic['对比%s-金额' % str(ix)] = text_list[i + 1]
data_dic['对比%s-地点' % str(ix)] = text_list[i + 3]
ix += 1
data_list.append(data_dic)
print('>>>>>>>>>>>>>>>>>>')
print(text_str)
# 关闭最新窗口
# 跳转到新页面进行完一系列操作后
driver.close() # 关闭新开的页面
time.sleep(2)
driver.switch_to.window(driver.window_handles[0]) # 跳转首页
df = pd.DataFrame(data_list)
df.to_excel('temp123.xlsx')
df = pd.DataFrame(data_list)
df.to_excel('temp123.xlsx')
return df
# 类引用
TaoBao().search_infor_price_from_web()
这段代码是一个使用Selenium自动化工具从淘宝网站上抓取商品信息的Python脚本。代码的主要功能是通过模拟浏览器操作,登录淘宝,搜索指定商品,并提取商品的价格、描述和地点等信息,最后将这些信息保存到Excel文件中。以下是对上述代码的详细解读
2 代码解读
2.1 导入模块
import datetime
import os
import time
import pandas as pd
import win32api
import win32con
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
datetime
、os
、time
:用于处理日期、时间和文件路径。pandas
:用于数据处理和保存到Excel文件。win32api
、win32con
:用于访问Windows注册表,获取下载路径。selenium
:用于自动化浏览器操作,模拟用户行为。
2.2 定义 TaoBao
类
class TaoBao():
这个类封装了从淘宝网站抓取商品信息的功能。
2.3 search_infor_price_from_web
方法
def search_infor_price_from_web(self, path_dir=os.path.abspath(r'.'), descr_list=['脱脂纱布', '机器人', '衬衫']):
这是类中的主要方法,用于从淘宝网站抓取商品信息。
path_dir
:指定保存文件的路径,默认为当前目录。descr_list
:要搜索的商品列表,默认为['脱脂纱布', '机器人', '衬衫']
。
2.3.1 获取下载路径
key1 = win32api.RegOpenKey(win32con.HKEY_CURRENT_USER,
r'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders', 0,
win32con.KEY_READ)
download_path = win32api.RegQueryValueEx(key1, 'Desktop')[0]
download_path = os.path.join(os.path.dirname(download_path), 'Downloads')
print(download_path)
通过访问Windows注册表,获取用户的桌面路径,并将其修改为下载路径(
Downloads
文件夹)。
2.3.2 设置浏览器选项
options = Options()
prefs = {'download.prompt_for_download': False, 'download.default_directory': download_path}
options.add_experimental_option("prefs", prefs)
设置Chrome浏览器的下载选项,禁用下载提示,并指定下载路径。
2.3.3 反爬虫处理
options.add_experimental_option('excludeSwitches', ['enable-automation']) # 去掉window.navigator.webdriver的特性
options.add_argument("--disable-blink-features=AutomationControlled")
通过修改浏览器选项,避免被网站识别为自动化脚本。
2.3.4 启动浏览器
driver = webdriver.Chrome(options=options)
启动Chrome浏览器,应用之前设置的选项。
2.3.5 修改浏览器属性
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument",
{"source": """Object.defineProperty(navigator, 'webdriver', {get: () => undefined})"""})
通过执行Chrome DevTools Protocol命令,修改浏览器的
navigator.webdriver
属性,避免被检测为自动化工具。
2.3.6 设置下载行为
driver.command_executor._commands["send_command"] = ("POST", '/session/$sessionId/chromium/send_command')
params = {'cmd': 'Page.setDownloadBehavior',
'params': {'behavior': 'allow', 'downloadPath': download_path}}
driver.execute("send_command", params)
设置浏览器的下载行为,允许下载并指定下载路径。
2.3.7 打开淘宝登录页面
driver.get('https://login.taobao.com/member/login.jhtml')
打开淘宝的登录页面。
2.3.8 登录淘宝
username = driver.find_element(By.ID, 'fm-login-id')
username.send_keys('XXXXX')
password = driver.find_element(By.ID, 'fm-login-password')
password.send_keys('XXXXX')
driver.find_element(By.XPATH, '/html/body/div/div[2]/div[3]/div/div/div/div[1]/div/form/div[6]/button').click()
通过输入用户名和密码,点击登录按钮,完成登录操作。
2.3.9 搜索商品并提取信息
for search_str in descr_list:
driver.find_element(By.XPATH, path).clear()
driver.find_element(By.XPATH, path).send_keys(search_str)
driver.find_element(By.XPATH, path).click()
遍历
descr_list
中的每个商品名称,输入搜索框并点击搜索按钮。
2.3.10 提取商品信息
text_str = driver.find_element(By.XPATH, path).text
text_list = text_str.split('\n')
从搜索结果页面中提取商品信息,并将其拆分为列表。
3.11 保存数据到Excel
df = pd.DataFrame(data_list)
df.to_excel('temp123.xlsx')
将提取的商品信息保存到Excel文件中。
2.4 执行脚本
TaoBao().search_infor_price_from_web()
创建
TaoBao
类的实例,并调用search_infor_price_from_web
方法,执行整个抓取过程。
3 总结与思考
这段代码通过Selenium模拟浏览器操作,实现了从淘宝网站抓取商品信息的功能。代码中使用了多种反爬虫技术,避免被网站检测为自动化脚本。最终,抓取到的商品信息被保存到Excel文件中,便于后续分析和处理。