项目工坊 | 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文件中,便于后续分析和处理。

相关推荐
山烛1 小时前
决策树学习全解析:从理论到实战
人工智能·python·学习·算法·决策树·机器学习
没有梦想的咸鱼185-1037-16633 小时前
Python科研数据可视化技术
python·机器学习·信息可视化·数据分析
奔波霸的伶俐虫4 小时前
jeecg框架@Dict不生效问题
开发语言·python
徐赛俊5 小时前
# 自动定时运行Python爬虫脚本教程(Windows任务计划程序)
windows·爬虫·python
程序员秘密基地5 小时前
基于html,css,jquery,django,lstm,cnn,tensorflow,bert,推荐算法,mysql数据库
python·cnn·tensorflow·lstm·推荐算法
技术炼丹人6 小时前
从RNN为什么长依赖遗忘到注意力机制的解决方案以及并行
人工智能·python·算法
hqxstudying6 小时前
Java开发时出现的问题---语言特性与基础机制陷阱
java·jvm·python
仪器科学与传感技术博士6 小时前
python:机器学习中的分类与回归怎么理解
python·机器学习·分类
CodeCraft Studio7 小时前
使用 Aspose.OCR 将图像文本转换为可编辑文本
java·人工智能·python·ocr·.net·aspose·ocr工具
allenXer7 小时前
Flask全栈入门:打造区块链艺术品交易所
python·flask·区块链