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

相关推荐
Ronin-Lotus35 分钟前
深度学习篇---Opencv中的机器学习和深度学习
python·深度学习·opencv·机器学习
信阳农夫1 小时前
Django解析跨域问题
后端·python·django
m0_371356152 小时前
【测试语言基础篇】Python基础之List列表
开发语言·python·list
大0马浓2 小时前
训练大模型LLM选择哪种开发语言最好
人工智能·python·训练
风筝超冷2 小时前
AttributeError: module ‘backend_interagg‘ has no attribute ‘FigureCanvas‘
python
onejason2 小时前
如何利用爬虫获取腾讯新闻详情数据:实战指南
前端·python
yicode3 小时前
Python基础:列表与元组详解
后端·python
梦丶晓羽3 小时前
自然语言处理:无监督朴素贝叶斯模型
人工智能·python·自然语言处理·tf-idf·贝叶斯定理·词袋模型·无监督朴素贝叶斯模型
Y雨何时停T3 小时前
使用 Python 批量提取 PDF 书签:一款实用工具的实现
python·pdf