项目工坊 | Python驱动淘宝信息爬虫

目录

前言

[1 完整代码](#1 完整代码)

[2 代码解读](#2 代码解读)

[2.1 导入模块](#2.1 导入模块)

[2.2 定义 TaoBao 类](#2.2 定义 TaoBao 类)

[2.3 search_infor_price_from_web 方法](#2.3 search_infor_price_from_web 方法)

[2.3.1 获取下载路径](#2.3.1 获取下载路径)

[2.3.2 设置浏览器选项](#2.3.2 设置浏览器选项)

[2.3.3 反爬虫处理](#2.3.3 反爬虫处理)

[2.3.4 启动浏览器](#2.3.4 启动浏览器)

[2.3.5 修改浏览器属性](#2.3.5 修改浏览器属性)

[2.3.6 设置下载行为](#2.3.6 设置下载行为)

[2.3.7 打开淘宝登录页面](#2.3.7 打开淘宝登录页面)

[2.3.8 登录淘宝](#2.3.8 登录淘宝)

[2.3.9 搜索商品并提取信息](#2.3.9 搜索商品并提取信息)

[2.3.10 提取商品信息](#2.3.10 提取商品信息)

[3.11 保存数据到Excel](#3.11 保存数据到Excel)

[2.4 执行脚本](#2.4 执行脚本)

[3 总结与思考](#3 总结与思考)


前言

Selenium作为主流的Web自动化测试框架,在数据采集领域也有广泛应用。本文将分享如何使用Selenium实现淘宝物资价格信息的爬取。目前代码还存在一些缺陷,主要体现在:1)未能有效绕过淘宝的反爬虫机制;2)登录环节仍需人工干预。欢迎大伙在评论区分享解决方案。

1 完整代码

python 复制代码
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 导入模块

python 复制代码
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
  • datetimeostime:用于处理日期、时间和文件路径。

  • pandas:用于数据处理和保存到Excel文件。

  • win32apiwin32con:用于访问Windows注册表,获取下载路径。

  • selenium:用于自动化浏览器操作,模拟用户行为。

2.2 定义 TaoBao

python 复制代码
class TaoBao():
  • 这个类封装了从淘宝网站抓取商品信息的功能。

2.3 search_infor_price_from_web 方法

python 复制代码
def search_infor_price_from_web(self, path_dir=os.path.abspath(r'.'), descr_list=['脱脂纱布', '机器人', '衬衫']):
  • 这是类中的主要方法,用于从淘宝网站抓取商品信息。

  • path_dir:指定保存文件的路径,默认为当前目录。

  • descr_list:要搜索的商品列表,默认为 ['脱脂纱布', '机器人', '衬衫']

2.3.1 获取下载路径

python 复制代码
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 设置浏览器选项

python 复制代码
options = Options()
prefs = {'download.prompt_for_download': False, 'download.default_directory': download_path}
options.add_experimental_option("prefs", prefs)
  • 设置Chrome浏览器的下载选项,禁用下载提示,并指定下载路径。

2.3.3 反爬虫处理

python 复制代码
options.add_experimental_option('excludeSwitches', ['enable-automation'])  # 去掉window.navigator.webdriver的特性
options.add_argument("--disable-blink-features=AutomationControlled")
  • 通过修改浏览器选项,避免被网站识别为自动化脚本。

2.3.4 启动浏览器

python 复制代码
driver = webdriver.Chrome(options=options)
  • 启动Chrome浏览器,应用之前设置的选项。

2.3.5 修改浏览器属性

python 复制代码
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument",
                       {"source": """Object.defineProperty(navigator, 'webdriver', {get: () => undefined})"""})
  • 通过执行Chrome DevTools Protocol命令,修改浏览器的navigator.webdriver属性,避免被检测为自动化工具。

2.3.6 设置下载行为

python 复制代码
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 打开淘宝登录页面

python 复制代码
driver.get('https://login.taobao.com/member/login.jhtml')
  • 打开淘宝的登录页面。

2.3.8 登录淘宝

python 复制代码
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 搜索商品并提取信息

python 复制代码
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 提取商品信息

python 复制代码
text_str = driver.find_element(By.XPATH, path).text
text_list = text_str.split('\n')
  • 从搜索结果页面中提取商品信息,并将其拆分为列表。

3.11 保存数据到Excel

python 复制代码
df = pd.DataFrame(data_list)
df.to_excel('temp123.xlsx')
  • 将提取的商品信息保存到Excel文件中。

2.4 执行脚本

python 复制代码
TaoBao().search_infor_price_from_web()
  • 创建TaoBao类的实例,并调用search_infor_price_from_web方法,执行整个抓取过程。

3 总结与思考

这段代码通过Selenium模拟浏览器操作,实现了从淘宝网站抓取商品信息的功能。代码中使用了多种反爬虫技术,避免被网站检测为自动化脚本。最终,抓取到的商品信息被保存到Excel文件中,便于后续分析和处理。

相关推荐
Y3174299 分钟前
Python Day23 学习
python·学习
Ai尚研修-贾莲1 小时前
Python语言在地球科学交叉领域中的应用——从数据可视化到常见数据分析方法的使用【实例操作】
python·信息可视化·数据分析·地球科学
qq_508576092 小时前
if __name__ == ‘__main__‘
python
学地理的小胖砸2 小时前
【Python 基础语法】
开发语言·python
程序员小远2 小时前
自动化测试与功能测试详解
自动化测试·软件测试·python·功能测试·测试工具·职场和发展·测试用例
_Itachi__2 小时前
Model.eval() 与 torch.no_grad() PyTorch 中的区别与应用
人工智能·pytorch·python
(・Д・)ノ3 小时前
python打卡day22
python
achene_ql3 小时前
深入探索 RKNN 模型转换之旅
python·目标检测·rk3588·模型部署·rk3566
@十八子德月生4 小时前
8天Python从入门到精通【itheima】-1~5
大数据·开发语言·python·学习
每天一个秃顶小技巧5 小时前
02.Golang 切片(slice)源码分析(一、定义与基础操作实现)
开发语言·后端·python·golang