当前位置: 首页 > article >正文

项目工坊 | 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
  • datetimeostime:用于处理日期、时间和文件路径。

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

  • win32apiwin32con:用于访问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文件中,便于后续分析和处理。


http://www.kler.cn/a/572917.html

相关文章:

  • CSS设置文字渐变色样式(附带动画效果)
  • 鸿蒙5.0实战案例:基于OpenGL渲染视频画面帧
  • 网络编程之TCP协议
  • 数据结构:八大排序(冒泡,堆,插入,选择,希尔,快排,归并,计数)详解
  • CHAPTER 5 Data Class Builders
  • MWC 2025 | 移远通信大模型解决方案加速落地,引领服务机器人创新变革
  • Tripo3D使用体验
  • C语言_图书管理系统_借阅系统管理
  • E22-xxxT22D lora模块配置
  • OpenFeign 学习笔记
  • 并查集—数组实现
  • 【Linux】进程间通信 续
  • 美颜SDK架构揭秘:人脸美型API的底层实现与优化策略
  • 立体仓WMS同MES制造的协同
  • upload-labs Pass5-18 文件上传
  • 观察者模式的C++实现示例
  • 从零开始的kafka学习 (一)| 概念,Java API
  • 从vue源码解析Vue.set()和this.$set()
  • 深入浅出:UniApp 从入门到精通全指南
  • 360图片搜索爬虫|批量爬取搜索图片