出师未捷身先死的sycm数据自动化

2022-05-09 18:54:31 浏览数 (1)

淘宝生意参谋数据自动化采集, 前面做了情报通的自动化采集 原文链接: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)

0 人点赞