python爬取企查查企业信息之selenium自动模拟登录企查查


Posted in Python onApril 08, 2021

最近接了个小项目需要批量搜索企查查上的相关企业并把指定信息保存到Excel文件中,由于企查查需要登录后才能查看所有搜索到的信息所以第一步需要模拟登录企查查。

python模拟登录企查查最重要的是自动拖拽验证插件

python爬取企查查企业信息之selenium自动模拟登录企查查

先介绍下项目中使用到的工具与库

Python的selenium库:

Web应用程序测试的工具,Selenium可以模拟用户在浏览器中的操作,就像真实用户使用一样。

官方技术文档:https://www.selenium.dev/selenium/docs/api/py/index.html

Chrome浏览器:

谷歌浏览器,不作过多介绍

Chromedriver:

配合Selenium操作Chrome浏览器的驱动程序,注意在下载Chromedriver时必须与已安装的Chrome浏览器版本号前3位保持一至

官方下载地址:http://chromedriver.storage.googleapis.com/index.html

 

第一步:下载配置Chromedriver

假设电脑中已安装Chrome最新版(如果没有安装请自行下载安装),下载与电脑系统、Chrome版本相匹配的版本(Chromedriver的版本号必须与安装的Chrome版本号一至)。

python爬取企查查企业信息之selenium自动模拟登录企查查

从官网下载的文件是一个压缩包,解压出Chromedriver.exe文件,

网上有很多文章说要正常使用Chromedriver.exe,需要配置系统的环境变量,其实这是一种比较麻烦的方法。

为了项目的可移动性和操作方便使用另一种方法,就是把Chrome浏览器安装目录下的整个Application目录都复制到项目目录下,这样就可以随便移动项目到新开发环境中而不用考虑新环境的系统环境变量了。

python爬取企查查企业信息之selenium自动模拟登录企查查

把解压出Chromedriver.exe文件复制到项目目录下的从Chrome浏览器安装目录中复制过来的Application目录下,保证Chromedriver.exe文件与chrome.exe文件在同一目录下。

python爬取企查查企业信息之selenium自动模拟登录企查查

第二步:安装selenium库

pip安装selenium库

pip install selenium

Pycharm开发工具安装selenium库

在Pycharm菜单栏中找到并点击【file】->【settings】

python爬取企查查企业信息之selenium自动模拟登录企查查

在弹出窗口中按下图所示操作

python爬取企查查企业信息之selenium自动模拟登录企查查

第三步:自动模拟登录企查查python代码编写

首先引入selenium相关库

import time
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

初始化webdriver基本配置参数

options = webdriver.ChromeOptions()
    # options.add_argument('--headless')  # 开启无界面模式
    options.add_argument('--disable-gpu')  # 禁用gpu,解决一些莫名的问题
    options.add_argument('blink-settings=imagesEnabled=false')  # 不加载图片, 提升速度
    options.add_argument('--disable-infobars')  # 禁用浏览器正在被自动化程序控制的提示
    options.add_argument('--start-maximized')
    options.add_experimental_option("excludeSwitches", ["enable-automation"])
    options.add_experimental_option('useAutomationExtension', False)
    d = DesiredCapabilities.CHROME
    d['goog:loggingPrefs'] = {'performance': 'ALL'}# 获取Headers必须参数
    driver = webdriver.Chrome(options=options, executable_path="Application/chromedriver.exe", desired_capabilities=d)
    driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {#清除验证插件中windows.navigator.webdriver的值
        "source": """
        Object.defineProperty(navigator, 'webdriver', {
          get: () => undefined
        })
      """
    })

模拟用户在页面中的一系列操作

driver.implicitly_wait(2)#延时
    driver.set_window_size(width=800, height=600)
    driver.get("https://www.QCC.com/")
    driver.find_element_by_xpath('//a[@class="navi-btn"][1]').click()
    locator = (By.ID, "dom_id_two")
    try:
        WebDriverWait(driver, 20, 0.5).until(EC.presence_of_element_located(locator))
    except:
        driver.close()
    # WebDriverWait(driver,20,0.5).until(lambda driver:driver.find_element_by_xpath('//span[@class="nc_iconfont btn_slide"]'))
    # 找到账号输入框
    driver.find_element_by_xpath('//input[@id="nameVerify"]').send_keys('手机号')

自动拖动验证插件滑块并验证

验证插件会检测浏览器是否为webdriver即使用JS检查windows.navigator.webdriver值

所以需要在页面加载前手动修改windows.navigator.webdriver值

driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
        "source": """
        Object.defineProperty(navigator, 'webdriver', {
          get: () => undefined
        })
      """
    })

修改完成windows.navigator.webdriver值后再模拟拖动验证插件滑块

# 滑动条定位
    start = driver.find_element_by_xpath('//span[@class="nc_iconfont btn_slide"]')
    action = ActionChains(driver)
    action.click_and_hold(start)
    action.drag_and_drop_by_offset(start, 308, 0).perform()

检查验证是否成功

time.sleep(2)
    style = 'position:absolute;top:0;left:0;width:100%;z-index:999;font-size:40px;line-height:100px;background:rgba(255,217,0,90%);height:100%;text-align:center;color:#000;'
    driver.execute_script(
        'var htm=document.getElementsByClassName("login-sao-panel")[0];htm.innerHTML+="<div style={style}><b id=tt></b><b id=ts></b></div>"'.format(
            style=style))

    ts = driver.find_element_by_id('ts')
    tt = driver.find_element_by_id('tt')

    try:
        driver.find_element_by_xpath('//div[@class="errloading"][1]')
        set_id_att(driver, 'tt', 'innerHTML', '请手工验证')
    except:
        tr = driver.find_element_by_xpath('//span[@class="nc-lang-cnt"][1]')
        if tr.text != '验证通过':
            set_id_att(driver, 'tt', 'innerHTML', '请手工验证')
            # for i in range(1, 6):
            #    if tr.text == '验证通过':
            #        break
            #    set_id_att(driver, 'ts', 'innerHTML', i)
            #    time.sleep(1)
    try:
        driver.find_element_by_xpath('//a[@class="text-primary vcode-btn get-mobile-code"]').click()
    except:
        pass
    # code=driver.find_element_by_xpath('//input[@id="vcodeNormal"]')
    set_id_att(driver, 'tt', 'innerHTML', '请填入手机验证码')
    # rjs='const callback = arguments[arguments.length - 1];callback({v:document.getElementById("vcodeNormal").value})'
    rjs = 'return document.getElementById("vcodeNormal").value'
    locator = (By.CLASS_NAME, "nav-user")
    but = driver.find_element_by_xpath('//form[@id="user_login_verify"]/button')
    for i in range(1, 1):
        # code = driver.execute_async_script(rjs)
        code = driver.execute_script(rjs)
        if len(code) == 6:
            but.click()
            try:
                #WebDriverWait(driver, 5, 0.5).until(EC.presence_of_element_located(locator))
                break
            except:
                pass
                #return 0
        set_id_att(driver, 'ts', 'innerHTML', i)
        time.sleep(1)

上面的代码中在页面里增加了一些状态显示元素及JS代码

style = 'position:absolute;top:0;left:0;width:100%;z-index:999;font-size:40px;line-height:100px;background:rgba(255,217,0,90%);height:100%;text-align:center;color:#000;'
    driver.execute_script(
        'var htm=document.getElementsByClassName("login-sao-panel")[0];htm.innerHTML+="<div style={style}><b id=tt></b><b id=ts></b></div>"'.format(
            style=style))

把selenium访问页面元素写成函数方便以后操作

def set_id_att(bor, id, att, val):
    bor.execute_script('document.getElementById("{a}").{b}="{c}"'.format(a=id, b=att, c=val))

def set_class_att(bor, classs, id, att, val):
    bor.execute_script('document.getElementsByClassName("{a}")[{d}].{b}="{c}"'.format(a=classs, b=att, c=val, d=id))

登录成功后还需要获取页面的headers、Cookie方便后面的requests库使用

selenium获取页面headers头部信息

def getheader(browser):
    for responseReceived in browser.get_log('performance'):
        try:
            response = json.loads(responseReceived[u'message'])[u'message'][u'params'][u'response']
            if response[u'url'] == browser.current_url:
                return response[u'requestHeaders']
        except:
            pass
    return None

selenium获取页面登录后Cookie

cookie = [item["name"] + "=" + item["value"] for item in driver.get_cookies()]
headers['cookie'] = ';'.join(item for item in cookie)

完整代码如下

import time
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

def getheader(browser):
    for responseReceived in browser.get_log('performance'):
        try:
            response = json.loads(responseReceived[u'message'])[u'message'][u'params'][u'response']
            if response[u'url'] == browser.current_url:
                return response[u'requestHeaders']
        except:
            pass
    return None

def set_id_att(bor, id, att, val):
    bor.execute_script('document.getElementById("{a}").{b}="{c}"'.format(a=id, b=att, c=val))

def set_class_att(bor, classs, id, att, val):
    bor.execute_script('document.getElementsByClassName("{a}")[{d}].{b}="{c}"'.format(a=classs, b=att, c=val, d=id))

def login():
    options = webdriver.ChromeOptions()
    # options.add_argument('--headless')  # 开启无界面模式
    options.add_argument('--disable-gpu')  # 禁用gpu,解决一些莫名的问题
    options.add_argument('blink-settings=imagesEnabled=false')  # 不加载图片, 提升速度
    options.add_argument('--disable-infobars')  # 禁用浏览器正在被自动化程序控制的提示
    options.add_argument('--start-maximized')
    options.add_experimental_option("excludeSwitches", ["enable-automation"])
    options.add_experimental_option('useAutomationExtension', False)
    d = DesiredCapabilities.CHROME
    d['goog:loggingPrefs'] = {'performance': 'ALL'}
    driver = webdriver.Chrome(options=options, executable_path="Application/chromedriver.exe", desired_capabilities=d)
    driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
        "source": """
        Object.defineProperty(navigator, 'webdriver', {
          get: () => undefined
        })
      """
    })
    driver.implicitly_wait(2)
    driver.set_window_size(width=800, height=600)
    driver.get("https://www.QCC.com/",)
    driver.find_element_by_xpath('//a[@class="navi-btn"][1]').click()
    locator = (By.ID, "dom_id_two")
    try:
        WebDriverWait(driver, 20, 0.5).until(EC.presence_of_element_located(locator))
    except:
        driver.close()
    # WebDriverWait(driver,20,0.5).until(lambda driver:driver.find_element_by_xpath('//span[@class="nc_iconfont btn_slide"]'))
    # 找到账号输入框
    driver.find_element_by_xpath('//input[@id="nameVerify"]').send_keys('19942496979')
    # 滑动条定位
    start = driver.find_element_by_xpath('//span[@class="nc_iconfont btn_slide"]')
    action = ActionChains(driver)
    action.click_and_hold(start)
    action.drag_and_drop_by_offset(start, 308, 0).perform()
    time.sleep(2)
    style = 'position:absolute;top:0;left:0;width:100%;z-index:999;font-size:40px;line-height:100px;background:rgba(255,217,0,90%);height:100%;text-align:center;color:#000;'
    driver.execute_script(
        'var htm=document.getElementsByClassName("login-sao-panel")[0];htm.innerHTML+="<div style={style}><b id=tt></b><b id=ts></b></div>"'.format(
            style=style))

    ts = driver.find_element_by_id('ts')
    tt = driver.find_element_by_id('tt')

    try:
        driver.find_element_by_xpath('//div[@class="errloading"][1]')
        set_id_att(driver, 'tt', 'innerHTML', '请手工验证')
    except:
        tr = driver.find_element_by_xpath('//span[@class="nc-lang-cnt"][1]')
        if tr.text != '验证通过':
            set_id_att(driver, 'tt', 'innerHTML', '请手工验证')
            # for i in range(1, 6):
            #    if tr.text == '验证通过':
            #        break
            #    set_id_att(driver, 'ts', 'innerHTML', i)
            #    time.sleep(1)
    try:
        driver.find_element_by_xpath('//a[@class="text-primary vcode-btn get-mobile-code"]').click()
    except:
        pass
    # code=driver.find_element_by_xpath('//input[@id="vcodeNormal"]')
    set_id_att(driver, 'tt', 'innerHTML', '请填入手机验证码')
    # rjs='const callback = arguments[arguments.length - 1];callback({v:document.getElementById("vcodeNormal").value})'
    rjs = 'return document.getElementById("vcodeNormal").value'
    locator = (By.CLASS_NAME, "nav-user")
    but = driver.find_element_by_xpath('//form[@id="user_login_verify"]/button')
    for i in range(1, 1):
        # code = driver.execute_async_script(rjs)
        code = driver.execute_script(rjs)
        if len(code) == 6:
            but.click()
            try:
                #WebDriverWait(driver, 5, 0.5).until(EC.presence_of_element_located(locator))
                break
            except:
                pass
                #return 0
        set_id_att(driver, 'ts', 'innerHTML', i)
        time.sleep(1)

    headers = getheader(driver)#获取headers
    ip = "202.121.178.244"
    if headers:
        #获取cookie并存入headers中
        cookie = [item["name"] + "=" + item["value"] for item in driver.get_cookies()]
        headers['cookie'] = ';'.join(item for item in cookie)
        del headers[':authority']
        del headers[':method']
        del headers[':path']
        del headers[':scheme']
        headers['X-Forwarded-For'] = ip
        headers['X-Remote-IP'] = ip
        headers['X-Originating-IP'] = ip
        headers['X-Remote-Addr'] = ip
        headers['X-Client-IP'] = ip
    return headers

headers=login()#自动登录并获取登录后的Headers包括cookies

本文主要介绍了如何使用python的selenium模拟登录企查查,主要介绍了如何使用selenium保存Cookies与headers、自动验证及selenium库对页面元素的一些操作方法。

Python 相关文章推荐
零基础学Python(一)Python环境安装
Aug 20 Python
详细解读Python的web.py框架下的application.py模块
May 02 Python
Python基于dom操作xml数据的方法示例
May 12 Python
python 阶乘累加和的实例
Feb 01 Python
深入解析python中的实例方法、类方法和静态方法
Mar 11 Python
python实现远程控制电脑
May 23 Python
python儿童学游戏编程知识点总结
Jun 03 Python
tensorflow -gpu安装方法(不用自己装cuda,cdnn)
Jan 20 Python
Python django框架开发发布会签到系统(web开发)
Feb 12 Python
Python实现的北京积分落户数据分析示例
Mar 27 Python
Python telnet登陆功能实现代码
Apr 16 Python
python+opencv实现车道线检测
Feb 19 Python
Python3 使用pip安装git并获取Yahoo金融数据的操作
Apr 08 #Python
Django 如何实现文件上传下载
Apr 08 #Python
python3 删除所有自定义变量的操作
Apr 08 #Python
pytorch显存一直变大的解决方案
Apr 08 #Python
Python文件的操作示例的详细讲解
Django展示可视化图表的多种方式
python tkinter模块的简单使用
You might like
用来给图片加水印的PHP类
2008/04/09 PHP
php array_intersect比array_diff快(附详细的使用说明)
2011/07/03 PHP
php自定义urlencode,urldecode函数实例
2015/03/24 PHP
PHP运用foreach神奇的转换数组(实例讲解)
2018/02/01 PHP
one.php 多项目、函数库、类库 统一为一个版本的方法
2020/08/24 PHP
DOM相关内容速查手册
2007/02/07 Javascript
使用jQuery的ajax功能实现的RSS Reader 代码
2009/09/03 Javascript
网页自动跳转代码收集
2009/09/27 Javascript
js 效率组装字符串 StringBuffer
2009/12/23 Javascript
js压缩工具 yuicompressor 使用教程
2010/03/31 Javascript
ECMAScript6中Map/WeakMap详解
2015/06/12 Javascript
Javascript使用function创建类的两种方法(推荐)
2016/11/19 Javascript
ES6正则表达式的一些新功能总结
2017/05/09 Javascript
微信小程序与php 实现微信支付的简单实例
2017/06/23 Javascript
NodeJS收发GET和POST请求的示例代码
2017/08/25 NodeJs
浅谈webpack打包生成的bundle.js文件过大的问题
2018/02/22 Javascript
JS实现图片拖拽交换效果
2018/11/30 Javascript
微信小程序封装的HTTP请求示例【附升级版】
2019/05/11 Javascript
javascript利用键盘控制小方块的移动
2020/04/20 Javascript
剖析Python的Tornado框架中session支持的实现代码
2015/08/21 Python
Python中字符串格式化str.format的详细介绍
2017/02/17 Python
python生成密码字典的方法
2018/07/06 Python
python爬虫之线程池和进程池功能与用法详解
2018/08/02 Python
在Qt中正确的设置窗体的背景图片的几种方法总结
2019/06/19 Python
Python中print函数简单使用总结
2019/08/05 Python
Python的PIL库中getpixel方法的使用
2020/04/09 Python
Python键鼠操作自动化库PyAutoGUI简介(小结)
2020/05/17 Python
Django filter动态过滤与排序实现过程解析
2020/11/26 Python
英国最大的网上药品商店:Chemist Direct
2017/12/16 全球购物
C语言笔试集
2012/07/24 面试题
项目总经理岗位职责
2014/02/14 职场文书
博士毕业生自我鉴定范文
2014/04/13 职场文书
群众路线教育实践活动个人对照检查材料思想汇报(社区班子)
2014/10/06 职场文书
寒暑假实习证明书模板
2014/11/29 职场文书
学校运动会简讯
2015/07/20 职场文书
python playwrigh框架入门安装使用
2022/07/23 Python