淘宝生意参谋数据自动化采集, 前面做了情报通的自动化采集 原文链接:https://blog.csdn.net/qq_35866846/article/details/103298524 so easy 老板发话让搞下sycm,我以为跟qbt一样简单 结果打脸了,真真是出师未捷身先死啊! 登录界面搞了一周,最后还是手动登录的 不得不说tb是真的强大, 感受下写了多少版本,中间走了不少弯路,也是技术不太行,绕过cookies应该是可以的,对应的2、3、4用了三种方法绕,最后绕过去了,但是不稳定,容易掉线,windows是pywin32可以访问,但是不太懂windows的句柄操作,就放弃了,还有其他版本都是对应网上资料一点点儿试的,最后登进去就很简单了
所以这次爬虫有一个难点,一个坑(这个坑填了半天) 难点:绕过反爬机制检测 坑:鼠标悬停,点击一次调出浮窗,再点击一次关闭浮窗,没有浮窗,悬停无法交互,所以很坑
绕过反爬机制检测:网上很多种方法,最后还是这个靠谱,还有其他的,有兴趣的可以试试,我是没成功
代码语言:javascript复制#修改windows.navigator.webdriver,防机器人识别机制,selenium自动登陆判别机制
chrome_options.add_experimental_option('excludeSwitches', ['enable-automation'])
就是绕过这个玩意
当出现这个玩意的时候,手动人工登录也不让你登,会出现滑块儿验证,但是你怎么都验证不过去, 不得不说,阿里真会玩人 简单说下原因,也是这几天查了无数资料了解到的, 原本最安全最仿真的selenium库从18年开始受到各方平台压榨,就是你的selenium是可以被检测出来的,高端玩家像sycm直接不让你玩了,其他小型平台还是不会管你的,只要你不是太过分挤得人家服务器不能用了,所以爬虫——要轻点儿来!
检测机制:selenium调用驱动打开浏览器,在控制台windows.navigator.webdriver会标记FALSE,手工正常打开的浏览器控制台windows.navigator.webdriver的结果是True,所以网上对应还用种方法,post请求时截断某文件,强行修改参数,我用的这个方法是调用驱动时添加控制参数,不知道有什么区别,我没截断成功
代码语言:javascript复制from selenium import webdriver
import time,os,shutil
from lxml import etree # xpath解析库
import requests,random
import pandas as pd
import numpy as np
from selenium.webdriver.common.action_chains import ActionChains
import datetime
#手动登录并点击到市场大盘
def login(extension_path,tmp_path):
chrome_options = webdriver.ChromeOptions()
# 设置好应用扩展
chrome_options.add_extension(extension_path)
#添加下载路径
prefs = {'profile.default_content_settings.popups': 0, 'download.default_directory':tmp_path}
chrome_options.add_experimental_option('prefs', prefs)
#修改windows.navigator.webdriver,防机器人识别机制,selenium自动登陆判别机制
chrome_options.add_experimental_option('excludeSwitches', ['enable-automation'])
drive = webdriver.Chrome(chrome_options=chrome_options)
url = 'https://sycm.taobao.com/portal/home.htm'
drive.get(url)
input("请手动登录,成功后输入【1】:")
#叉掉页面无关元素后再输入1继续执行
drive.find_element_by_xpath('//*[@id="app"]/div/div[1]/div[2]/section[2]/div/div[1]/ul/li[14]/a/span').click()#点击市场
tm=random.uniform(1,4)
time.sleep(tm)
drive.find_element_by_xpath('//*[@id="app"]/div/div[1]/div[3]/div[1]/aside/div/ul/li[2]/ul/li[1]/a/span').click()#点击市场大盘
tm=random.uniform(1,4)
time.sleep(tm)
drive.maximize_window() #窗口最大化
tm=random.uniform(1,4)
time.sleep(tm)
return drive
#点击各指标加载数据
def load_data(drive):
for i in [1,2]:
for j in range(1,6):
drive.find_element_by_xpath('//*[@id="cateTrend"]/div[2]/div/div[1]/div/div/div[%s]/div[%s]'%(i,j)).click()
tm=random.uniform(2,4)
time.sleep(tm)
def load_leimu(drive,start,end,tmp_path,data_path):
#获取当前查询日期
current_Date=drive.find_element_by_xpath('//*[@id="content-container"]/div[2]/div[2]/div[1]/div/div/div/div/div[1]/div[2]/div/div/div[1]').text[5:]
first_date=(pd.to_datetime(current_Date) datetime.timedelta(days=-30)).strftime('%Y-%m-%d')
#点击分类——打开悬浮
drive.find_element_by_xpath('//*[@id="content-container"]/div[2]/div[2]/div[1]/div/div/div/div/div[1]/div[1]/div/div/a').click()
#获得一级类目数量
links = drive.find_element_by_xpath('//*[@id="content-container"]/div[2]/div[2]/div[1]/div/div/div/div/div[1]/div[1]/div/div/div/div[2]/ul[2]').find_elements_by_tag_name("li")
leimu_num=len(links)
#点击分类——关闭悬浮
drive.find_element_by_xpath('//*[@id="content-container"]/div[2]/div[2]/div[1]/div/div/div/div/div[1]/div[1]/div/div/a').click()
for i in range(1,leimu_num 1):
#点击分类——打开悬浮
drive.find_element_by_xpath('//*[@id="content-container"]/div[2]/div[2]/div[1]/div/div/div/div/div[1]/div[1]/div/div/a').click()
level_1=drive.find_element_by_xpath('//*[@id="content-container"]/div[2]/div[2]/div[1]/div/div/div/div/div[1]/div[1]/div/div/div/div[2]/ul[2]/li[%s]'% i)
actions = ActionChains(drive).move_to_element(level_1).perform()#鼠标悬停在一级类目上
tm=random.uniform(1,2)
time.sleep(tm)
#获得二级类目个数
links_2 = drive.find_element_by_xpath('//*[@id="content-container"]/div[2]/div[2]/div[1]/div/div/div/div/div[1]/div[1]/div/div/div/div[2]/ul[1]').find_elements_by_tag_name("li")
leimu_num_2=len(links_2)
# print(leimu_num_2)#打印类目数量
#点击分类——关闭悬浮
drive.find_element_by_xpath('//*[@id="content-container"]/div[2]/div[2]/div[1]/div/div/div/div/div[1]/div[1]/div/div/a').click()
#获取二级类目
for j in range(1,leimu_num_2 1):
#点击分类——打开悬浮
drive.find_element_by_xpath('//*[@id="content-container"]/div[2]/div[2]/div[1]/div/div/div/div/div[1]/div[1]/div/div/a').click()
level_1=drive.find_element_by_xpath('//*[@id="content-container"]/div[2]/div[2]/div[1]/div/div/div/div/div[1]/div[1]/div/div/div/div[2]/ul[2]/li[%s]'% i)
actions = ActionChains(drive).move_to_element(level_1).perform()#鼠标悬停在一级类目上
# 获得一级类目名称——元素的title属性
title_1=level_1.get_attribute('title')
#替换类目名称里的特殊字符
title_1=title_1.replace("/","_")
level_2=drive.find_element_by_xpath('//*[@id="content-container"]/div[2]/div[2]/div[1]/div/div/div/div/div[1]/div[1]/div/div/div/div[2]/ul[1]/li[%s]'%j)
#获得二级类目名称——元素的title属性
title_2=level_2.get_attribute('title')
#替换类目名称里的特殊字符
title_2=title_2.replace("/","_")
# print(title)
#点击二级类目
level_2.click()
tm=random.uniform(3,5)
time.sleep(tm)
#加载二级类目下各指标数据
load_data(drive)
drive.find_element_by_xpath('//*[@id="xws-ext-tool"]/span').click()#小旺神转化
tm=random.uniform(2,5)
time.sleep(tm)
drive.find_element_by_xpath('//*[@id="xws-table_wrapper"]/div[1]/button[1]').click()#导出数据
tm=random.uniform(2,3)
time.sleep(tm)
f = os.listdir(tmp_path)[0]
while "crdownload" in f:
tm=random.uniform(3,4)
time.sleep(tm)
f = os.listdir(tmp_path)[0]
#注意替换类目名称里的路径字符
#找到老的文件所在的位置
old_file=os.path.join(tmp_path,f)
#指定新文件的位置
new_file=os.path.join(data_path,title_1 "—" title_2 start "—" end ".csv")
os.rename(old_file,new_file)
print("----------%s下载已完成---------"%(title_1 "—" title_2 start "—" end))
tm=random.uniform(3,5)
time.sleep(tm)
drive.find_element_by_xpath('//*[@id="xws-modal-block"]/div[2]/div/div[1]/button').click()#关闭小旺神
tm=random.uniform(2,4)
time.sleep(tm)
tm=random.uniform(4,5)
time.sleep(tm)
print("日期范围 %s —— %s 内所有二级类目数据下载完成"(current_Date,first_date))
return first_date
extension_path = r"xxx.crx"#加载小旺神
tmp_path="" #设置临时下载路径
data_path=''#设置文件重命名后存储路径
start_date=input("请输入开始日期:")#需要下载的开始日期
end_date=input("请输入结束日期:")#需要下载的结束日期
drive=login(extension_path,tmp_path)#登录并进入市场大盘
**#叉掉页面无关元素后再输入1继续执行** 一定要叉掉,否则无法读取页面元素
while end_date>=start_date:#校准日期序列
#获取页面日期
current_Date=drive.find_element_by_xpath('//*[@id="content-container"]/div[2]/div[2]/div[1]/div/div/div/div/div[1]/div[2]/div/div/div[1]').text[5:]
while current_Date!=(str(pd.to_datetime(end_date))[:10]):#校准页面日期
#点击上一天
drive.find_element_by_xpath('//*[@id="content-container"]/div[2]/div[2]/div[1]/div/div/div/div/div[1]/div[2]/div/div/div[2]/button[6]').click()
tm=random.uniform(1,3)
time.sleep(tm)
current_Date=drive.find_element_by_xpath('//*[@id="content-container"]/div[2]/div[2]/div[1]/div/div/div/div/div[1]/div[2]/div/div/div[1]').text[5:]
tm=random.uniform(1,3)
time.sleep(tm)
end=end_date
start=(pd.to_datetime(current_Date) datetime.timedelta(days=-29)).strftime('%Y-%m-%d')
end_date=load_leimu(drive,start,end,tmp_path,data_path)
tm=random.uniform(1,3)
time.sleep(tm)