项目工坊 | Python驱动淘宝信息爬虫
目录
前言
1 完整代码
2 代码解读
2.1 导入模块
2.2 定义 TaoBao 类
2.3 search_infor_price_from_web 方法
2.3.1 获取下载路径
2.3.2 设置浏览器选项
2.3.3 反爬虫处理
2.3.4 启动浏览器
2.3.5 修改浏览器属性
2.3.6 设置下载行为
2.3.7 打开淘宝登录页面
2.3.8 登录淘宝
2.3.9 搜索商品并提取信息
2.3.10 提取商品信息
3.11 保存数据到Excel
2.4 执行脚本
3 总结与思考
前言
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文件中,便于后续分析和处理。