Python自动化爬取天眼查数据的实现


Posted in Python onJune 15, 2021

首先要注册一个账号密码,通过账号密码登录,并且滑块验证,自动输入搜索关键词,进行跳转翻页爬取数据,并保存到Excel文件中。

代码运行时,滑块验证经常不通过,被吃掉,但是发现打包成exe运行没有这个问题,100%成功登录。如果大家知道这个问题麻烦请与我分享,谢谢!

Python自动化爬取天眼查数据的实现

废话不多说直接上代码

# coding=utf-8
from selenium import webdriver
import time
from PIL import Image, ImageGrab
from io import BytesIO
from selenium.webdriver.common.action_chains import ActionChains
import os
import sys
import re
import xlwt
import urllib
import datetime
 
'''
用于天眼查自动登录,解决滑块验证问题
'''
 
# 获取项目根目录
def app_path():
    if hasattr(sys, 'frozen'):
        return os.path.dirname(os.path.dirname(os.path.dirname(sys.executable))) #使用pyinstaller打包后的exe目录
    return os.path.dirname(__file__)
 
app_path = app_path()
 
ready_list = []
 
#设置表格样式
def set_style(name,height,bold=False):
    style = xlwt.XFStyle()
    font = xlwt.Font()
    font.name = name
    # font.bold = bold
    font.color_index = 4
    font.height = height
    style.font = font
    return style
 
# 写excel
f = xlwt.Workbook()
sheet1 = f.add_sheet('企查查数据',cell_overwrite_ok=True)
row0 = ["企业名称","法定代表人","注册资本","成立日期","电话","邮箱","地址"]
for i in range(0, len(row0)):
    sheet1.write(0, i, row0[i], set_style('Times New Roman', 220, True))
 
# 写列
def write_col(data, row, col):
    for i in range(0,len(data)):
        sheet1.write(row,col,data[i],set_style('Times New Roman',220,True))
        row = row + 1
 
def parse_save_data(all_list):
    row = 1
    for data in all_list:
        # 公司名称
        name_list = re.findall(r'<div class="info">(.*?)</div>',data)
        print(name_list)
 
        # 标签
        tag_list = re.findall(r'<div class="tag-list">(.*)</div><div class="info row text-ellipsis">', data)
        tags = []
        for list in tag_list:
            tag = re.findall(r'<div class="tag-common -primary -new">(.*?)</div>', list)
            tags.append(tag)
        # print(tags)
 
        # 法定代表人
        legal_list = re.findall(r'<a title="(.*?)" class="legalPersonName link-click"',data)
        # print(legal_list)
 
        # 注册资本
        registered_capital_list  = re.findall(r'注册资本:<span title="(.*?)">',data)
        # print(registered_capital_list)
 
        # 成立日期
        date_list  = re.findall(r'成立日期:<span title="(.*?)">',data)
        # print(date_list)
 
        # 电话
        tel_list  = re.findall(r'<div class="triangle" style=""></div><div class=""></div></div></div><span>(.*?)</span>',data)
        # print(tel_list)
 
        # 邮箱
        email_list  = re.findall(r'邮箱:</span><span>(.*?)</span>',data)
        # print(email_list)
 
        # 地址
        adress_list  = re.findall(r'地址:</span><span>(.*?)</span>',data)
        # print(adress_list)
        write_col(name_list,row,0)
        # write_col(tags,1)
        write_col(legal_list,row,1)
        write_col(registered_capital_list,row,2)
        write_col(date_list,row,3)
        write_col(tel_list,row,4)
        write_col(email_list,row,5)
        write_col(adress_list,row,6)
 
        row = row + len(name_list)
 
    s = str([datetime.datetime.now()][-1])
    name = '/天眼查数据' + s[:10] + s[-6:] + '.xls'
    f.save(app_path + name)
 
def get_track(distance):
    """
    根据偏移量获取移动轨迹
    :param distance: 偏移量
    :return: 移动轨迹
    """
    # 移动轨迹
    track = []
    # 当前位移
    current = 0
    # 减速阈值
    mid = distance * 2 / 5
    # 计算间隔
    t = 0.2
    # 初速度
    v = 1
 
    while current < distance:
        if current < mid:
            # 加速度为正2
            a = 5
        else:
            # 加速度为负3
            a = -2
        # 初速度v0
        v0 = v
        # 当前速度v = v0 + at
        v = v0 + a * t
        # 移动距离x = v0t + 1/2 * a * t^2
        move = v0 * t + 1 / 2 * a * t * t
        # 当前位移
        current += move
        # 加入轨迹
        track.append(round(move))
    return track
 
 
def autologin(account, password):
    count = 0
    global driver,page,keywords
    driver.get('https://www.tianyancha.com/?jsid=SEM-BAIDU-PP-SY-000873&bd_vid=7864822754227867779')
    time.sleep(3)
    try:
        driver.find_element_by_xpath('//*[@id="tyc_banner_close"]').click()
    except:
        pass
 
    driver.find_element_by_xpath('//div[@class="nav-item -home  -p10"]/a').click()
    time.sleep(3)
    # 这里点击密码登录时用id去xpath定位是不行的,因为这里的id是动态变化的,所以这里换成了class定位
    driver.find_element_by_xpath('.//div[@class="sign-in"]/div/div[2]').click()
    time.sleep(1)
    accxp = './/input[@id="mobile"]'
    pasxp = './/input[@id="password"]'
    driver.find_element_by_xpath(accxp).send_keys(account)
    driver.find_element_by_xpath(pasxp).send_keys(password)
    clixp = './/div[@class="sign-in"]/div[2]/div[2]'
    driver.find_element_by_xpath(clixp).click()
    # 点击登录之后开始截取验证码图片
    time.sleep(2)
    img = driver.find_element_by_xpath('/html/body/div[10]/div[2]/div[2]/div[1]/div[2]/div[1]')
    time.sleep(0.5)
    # 获取图片位子和宽高
    location = img.location
    size = img.size
    # 返回左上角和右下角的坐标来截取图片
    top, bottom, left, right = location['y'], location['y'] + size['height'], location['x'], location['x'] + size[
        'width']
    # 截取第一张图片(无缺口的)
    screenshot = driver.get_screenshot_as_png()
    screenshot = Image.open(BytesIO(screenshot))
    captcha1 = screenshot.crop((left, top, right, bottom))
    print('--->', captcha1.size)
    captcha1.save('captcha1.png')
    # 截取第二张图片(有缺口的)
    driver.find_element_by_xpath('/html/body/div[10]/div[2]/div[2]/div[2]/div[2]').click()
    time.sleep(4)
    img1 = driver.find_element_by_xpath('/html/body/div[10]/div[2]/div[2]/div[1]/div[2]/div[1]')
    time.sleep(0.5)
    location1 = img1.location
    size1 = img1.size
    top1, bottom1, left1, right1 = location1['y'], location1['y'] + size1['height'], location1['x'], location1['x'] + \
                                   size1['width']
    screenshot = driver.get_screenshot_as_png()
    screenshot = Image.open(BytesIO(screenshot))
    captcha2 = screenshot.crop((left1, top1, right1, bottom1))
    captcha2.save('captcha2.png')
    # 获取偏移量
    left = 55  # 这个是去掉开始的一部分
    for i in range(left, captcha1.size[0]):
        for j in range(captcha1.size[1]):
            # 判断两个像素点是否相同
            pixel1 = captcha1.load()[i, j]
            pixel2 = captcha2.load()[i, j]
            threshold = 60
            if abs(pixel1[0] - pixel2[0]) < threshold and abs(pixel1[1] - pixel2[1]) < threshold and abs(
                    pixel1[2] - pixel2[2]) < threshold:
                pass
            else:
                left = i
    print('缺口位置', left)
    # 减去缺口位移
    left -= 52
    # 开始移动
    track = get_track(left)
    print('滑动轨迹', track)
    # track += [5,4,5,-6, -3,5,-2,-3, 3,6,-5, -2,-2,-4]  # 滑过去再滑过来,不然有可能被吃
    # 拖动滑块
    slider = driver.find_element_by_xpath('/html/body/div[10]/div[2]/div[2]/div[2]/div[2]')
    ActionChains(driver).click_and_hold(slider).perform()
    for x in track:
        ActionChains(driver).move_by_offset(xoffset=x, yoffset=0).perform()
    time.sleep(0.2)
    ActionChains(driver).release().perform()
    time.sleep(1)
    try:
        if driver.find_element_by_xpath('/html/body/div[10]/div[2]/div[2]/div[2]/div[2]'):
            print('能找到滑块,重新试')
            # driver.delete_all_cookies()
            # driver.refresh()
            # autologin(driver, account, password)
        else:
            print('login success')
    except:
        print('login success')
 
    time.sleep(0.2)
    driver.find_element_by_xpath('.//input[@id="home-main-search"]').send_keys(keywords)
    driver.find_element_by_xpath('.//div[@class="input-group home-group"]/div[1]').click()
 
    # 爬数据
    data = driver.find_element_by_xpath('.//div[@class="result-list sv-search-container"]').get_attribute('innerHTML')
    count = count + 1
 
    # 添加待解析数据
    ready_list.append(data)
 
    while count < page:
        # 点击下一页
        # driver.find_element_by_xpath('./ul[@class="pagination"]]/li/a[@class="num -next"]').click()
        url = 'https://www.tianyancha.com/search/p{}?key={}'.format(count + 1,urllib.parse.quote(keywords))
        driver.get(url)
        time.sleep(2)
        data = driver.find_element_by_xpath('.//div[@class="result-list sv-search-container"]').get_attribute('innerHTML')
        count = count + 1
        ready_list.append(data)
 
    # 解析并写数据
    parse_save_data(ready_list)
    print('获取数据完毕')
 
        # if __name__ == '__main__':
    # driver_path = 'C:/Program Files (x86)/Google/Chrome/Application/chromedriver.exe'
    # chromeoption = webdriver.ChromeOptions()
    # chromeoption.add_argument('--headless')
    # chromeoption.add_argument('user-agent='+user_agent)
 
keywords = input('请输入关键词:')
account = input('请输入查天眼账号:')
password = input('请输入查天眼密码:')
page = int(input('请输入获取页数:'))
driver = webdriver.Chrome()
driver.maximize_window()
driver.implicitly_wait(10)
print('开始获取数据。。。')
autologin(account, password)

打包成exe(注意site-packages要换成自己python包的目录)

pyinstaller main.py -p D:\Anaconda3\Lib\site-packages

最终运行dist目录下的exe

Python自动化爬取天眼查数据的实现

注意事项

由于天眼查没有开会员只能查看到4页内容,所以需要开会员,这个想要绕过就需要另外去研究,毕竟是要充钱付费,破解也没那么简单

到此这篇关于Python自动化爬取天眼查数据的文章就介绍到这了,更多相关Python自动化爬取天眼查数据内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python编码时应该注意的几个情况
Mar 04 Python
python33 urllib2使用方法细节讲解
Dec 03 Python
Python实现类继承实例
Jul 04 Python
简单实现python进度条脚本
Dec 18 Python
Python使用matplotlib填充图形指定区域代码示例
Jan 16 Python
解决pandas 作图无法显示中文的问题
May 24 Python
PHP实现发送和接收JSON请求
Jun 07 Python
int在python中的含义以及用法
Jun 27 Python
pandas基于时间序列的固定时间间隔求均值的方法
Jul 04 Python
在python中利用pycharm自定义代码块教程(三步搞定)
Apr 15 Python
python 服务器运行代码报错ModuleNotFoundError的解决办法
Sep 16 Python
python制作抽奖程序代码详解
Jan 15 Python
浅谈Python响应式类库RxPy
Jun 14 #Python
Python Django ORM连表正反操作技巧
Python scrapy爬取起点中文网小说榜单
教你用Python爬取英雄联盟皮肤原画
使用qt quick-ListView仿微信好友列表和聊天列表的示例代码
python基础入门之普通操作与函数(三)
python基础入门之字典和集合
You might like
社区(php&amp;&amp;mysql)四
2006/10/09 PHP
CodeIgniter配置之routes.php用法实例分析
2016/01/19 PHP
PHP 对象接口简单实现方法示例
2020/04/13 PHP
用jQuery实现检测浏览器及版本的脚本代码
2008/01/22 Javascript
DOM2非标准但却支持很好的几个属性小结
2012/01/21 Javascript
Javascript改变CSS样式(局部和全局)
2013/12/18 Javascript
js 获取页面高度和宽度兼容 ie firefox chrome等
2014/05/14 Javascript
javascript实现动态导入js与css等静态资源文件的方法
2015/07/25 Javascript
JQuery日历插件My97DatePicker日期范围限制
2016/01/20 Javascript
js实现纯前端的图片预览
2016/04/27 Javascript
javascript实现的猜数小游戏完整实例代码
2016/05/10 Javascript
jquery表格datatables实例解析 直接加载和延迟加载
2016/08/12 Javascript
input file上传 图片预览功能实例代码
2016/10/25 Javascript
Angular中的$watch、$watchGroup、$watchCollection
2017/06/25 Javascript
详解javascript 正则表达式之分组与前瞻匹配
2018/05/30 Javascript
详解webpack loader和plugin编写
2018/10/12 Javascript
Ant Design Pro 之 ProTable使用操作
2020/10/31 Javascript
Vue中computed和watch有哪些区别
2020/12/19 Vue.js
Python中使用异常处理来判断运行的操作系统平台方法
2015/01/22 Python
10个易被忽视但应掌握的Python基本用法
2015/04/01 Python
在Python上基于Markov链生成伪随机文本的教程
2015/04/17 Python
ubuntu17.4下为python和python3装上pip的方法
2018/06/12 Python
python基于递归解决背包问题详解
2019/07/03 Python
python manage.py runserver流程解析
2019/11/08 Python
Python OpenCV实现测量图片物体宽度
2020/05/27 Python
Python3利用openpyxl读写Excel文件的方法实例
2021/02/03 Python
CSS3实现瀑布流布局与无限加载图片相册的实例代码
2016/12/22 HTML / CSS
英国山地公路自行车商店:Tweeks Cycles
2018/03/16 全球购物
农民入党思想汇报
2014/01/03 职场文书
生产部管理制度
2014/01/31 职场文书
高二物理教学反思
2014/02/08 职场文书
员工激励培训演讲稿
2014/09/16 职场文书
预备党员对照检查材料思想汇报
2014/09/24 职场文书
学校中秋节活动总结
2015/03/23 职场文书
计算机实训心得体会
2016/01/14 职场文书
SSM项目使用拦截器实现登录验证功能
2022/01/22 Java/Android