python之Selenium+pyquery爬取有大量反爬虫的天眼查 您所在的位置:网站首页 天眼查使用教程 python之Selenium+pyquery爬取有大量反爬虫的天眼查

python之Selenium+pyquery爬取有大量反爬虫的天眼查

2023-08-09 12:04| 来源: 网络整理| 查看: 265

天眼查:一个还有大量公司的信息的网站。 所以反爬程度是相当高的,首先直接用requests.get(url)来获取页面源代码,你会发现,明明显示在页面上的公司的一些数据都不在,他是利用其它的js的方法表达出来的,因为这个网站有专门的反爬虫人员,可以在一些招聘网上看到工资还可以15k-30k 所以说用这些方法根本就不爬到什么 那么只有使出我们的杀手锏,selenium,他的好处在于可以模拟浏览器操作,非常方便获取属性也很方便。 首先这个网站不登录的话,你会发现,怎么源代码上面的是和页面表示出来的不一样啊,明明是****公司**,在源代码上却是 @#¥····,连公司的基本信息,比如邮箱什么的,都是*****[email protected]什么的,不能看到全部的信息,这是因为不登录的话,天眼查对于大部分的公司的信息,进行了一些保护,登录了才可以页面的源代码才会正确。 所以首先我们注册注册一个天眼查的账号:这里写图片描述

接下来我们知道selenium驱动的浏览器是一个非常纯净的,没有任何cookies,及一些信息的保存,目前来说是这样,所以每一次访问这个网站,都是全新的,没有任何的登录信息在上面,所以我们怎么实现selenium模拟登录呢,这就要用到phantomjs,因为这个网站上面的登录注册时用js代码生成的,源代码上是没有这些东西的,如果我们用phantomjs的话,可以直接解析出来所有js包含的html代码。 下面一步一步来解析代码: 这是拼接完整的代码,keyword就是关键字,等会在main函数里自行输入,在search函数里加入phantomjs解析,这个要先安装好phantomjs。

browser = webdriver.Chrome() browser.maximize_window()#将浏览器最大化 wait = WebDriverWait(browser,10) def search(keyword): url_keyword = urllib.parse.quote(keyword) # 中文转码为url格式 url = 'http://www.tianyancha.com/search/' + url_keyword + '?checkFrom=searchBox' driver = webdriver.PhantomJS( executable_path='D:\\Program Files\\phantomjs-2.1.1-windows\\bin\\phantomjs') # phantomjs的绝对路径 time.sleep(2) driver.get(url) browser.get(url) return url def main(): keyword = '阿里巴巴' url = search(keyword) if __name__ == '__main__': main()

当我们运行代码后发现:怎么回事啊,为什么和我不加phantomjs代码不一样啊,现在直接出现一个登陆的界面,需要登陆之后才能进入,这就是为什么要注册一个账号的原因之一: 这里写图片描述 现在我们就需要利用selenuim模拟登录了,首先要做到的就是获取输入框,在刚刚这个界面按F12审查元素,再点击选择元素的小箭头,之后点击输入手机号码那里,就可以在下面看到输入框在源代码中的位置,找到那个位置,右键,copy,selector,就可以得到他的这个元素的选择器,因为我们用的是selenuim中一个查找元素为位置的元素,具体看我的代码,之后用send_keys()输入你的账户密码,然后同样的找到登录的那个位置的css_selector,再点击就进入了。

from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By from selenium.common.exceptions import TimeoutException def login(): try: userInput = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '#web-content > div > div > div > div.position-rel.container.company_container > div > div.in-block.vertical-top.float-right.right_content.mt50.mr5.mb5 > div.module.module1.module2.loginmodule.collapse.in > div.modulein.modulein1.mobile_box.pl30.pr30.f14.collapse.in > div.pb30.position-rel > input'))) passwordInput = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'#web-content > div > div > div > div.position-rel.container.company_container > div > div.in-block.vertical-top.float-right.right_content.mt50.mr5.mb5 > div.module.module1.module2.loginmodule.collapse.in > div.modulein.modulein1.mobile_box.pl30.pr30.f14.collapse.in > div.pb40.position-rel > input'))) userInput.send_keys('*************')#账号 passwordInput.send_keys('**********')#密码 changeLoginWay = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'#web-content > div > div > div > div.position-rel.container.company_container > div > div.in-block.vertical-top.float-right.right_content.mt50.mr5.mb5 > div.module.module1.module2.loginmodule.collapse.in > div.modulein.modulein1.mobile_box.pl30.pr30.f14.collapse.in > div.c-white.b-c9.pt8.f18.text-center.login_btn'))) changeLoginWay.click() except TimeoutException: login()

我们可以看到每个公司的class为search-result-single, 这里写图片描述 直接看代码: 这里就要用到pyquery了,用它来解析公司的每一个信息:具体pyquery使用方法就不详谈了,具体可以看我上一篇文章。

def get_company_info(): wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.search-block .result-list .search-result-single'))) html = browser.page_source#获取此时页面源代码 doc = pq(html) items = doc('.search-block .result-list .search-result-single').items()#解析到每一个公司的位置 for item in items: company = { 'urlInfo':item.find('.name ').attr('href'),#公司链接 'name' : item.find('.name').text(),#名字 'LegalRepresentative':item.find('.info .title a').text(),#法人 'registerMoney':item.find('.info .title span').eq(0).text(),#注册资金 'registerTime':item.find('.info .title span').eq(1).text(),#注册时间 'tel':item.find('.contact .link-hover-click').eq(0).text(),#电话 'email':item.find('.contact .link-hover-click').eq(1).text(),#邮箱 'LegalPersonInfo':item.find('.content .match span').eq(1).text()#商标信息 }

现在到了最关键的一步,就是翻页,因为有很多页,目前不是vip只有5页可以查找 下面是selenuim关于翻页的操作:这里面有很多坑,当时也折腾我了好久, 下面我来一一分析,当他在第一页的时候,下面有个企业认证的广告,刚好把翻页的按钮挡住了,当时这个bug我调了好久才找到,我们就用刚刚介绍的元素选择器把它关掉就行了,把它关掉才可以点击下一页那个按钮, 第二个坑出现了,居然第一页的下一步的按钮和第二页第三页的selector不一样,这里也调了很久,代码里可以看到我写了判断,最后再**执行get_company_info()**获取信息就行了。main里面的那个循环就是用来翻页的,从1到5页。 move_to_bottom是用来翻到网页最下面的。

def move_to_bottom(): js = "var q=document.documentElement.scrollTop=100000" browser.execute_script(js) def next_page(page_number): print('------------------------------------正在爬取',page_number,'页-----------------------------------------------------------------') try: if page_number == 2: closeAdvertisement = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'#tyc_banner_close'))) closeAdvertisement.click() move_to_bottom() if page_number == 2: nextPageButton = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'#web-content > div > div.container-left > div.search-block > div.result-footer > div:nth-child(1) > ul > li:nth-child(12) > a'))) nextPageButton.click() if page_number > 2: nextPageButton = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'#web-content > div > div.container-left > div.search-block > div.result-footer > div:nth-child(1) > ul > li:nth-child(13) > a'))) nextPageButton.click() get_company_info() time.sleep(3) except TimeoutException: next_page(page_number) def main(): keyword = '阿里巴巴' url = search(keyword) login() for page in range(2,6): next_page(page) browser.close()

最后存储到mongodb: 在get_company_info()方法里调用就行了。

import pymongo mongoclient = pymongo.MongoClient("localhost",port=27017,connect = False) db = mongoclient .AugEleventh classname = db.alibaba def save_to_mongo(result): if classname.insert(result): print('存储到mongoDB成功',result) else: print('存储到mongoDb失败')

这里告诉大家基本以及爬完了,你想爬什么公司的在keyword中输入就可以了,但是不是vip只有最多5页的内容。这个不用vip获取更多公司信息就说了,毕竟人家要靠这个赚钱,就放过他吧(其实是我完全不知道!!) 下面贴出完整代码:

from selenium import webdriver import urllib from pyquery import PyQuery as pq import json from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By from selenium.common.exceptions import TimeoutException import time import pymongo mongoclient = pymongo.MongoClient("localhost",port=27017,connect = False) db = mongoclient .AugEleventh classname = db.alibaba browser = webdriver.Chrome() browser.maximize_window()#将浏览器最大化 wait = WebDriverWait(browser,10) def move_to_bottom(): js = "var q=document.documentElement.scrollTop=100000" browser.execute_script(js) def search(keyword): url_keyword = urllib.parse.quote(keyword) # 中文转码为url格式 url = 'http://www.tianyancha.com/search/' + url_keyword + '?checkFrom=searchBox' driver = webdriver.PhantomJS( executable_path='D:\\Program Files\\phantomjs-2.1.1-windows\\bin\\phantomjs') # phantomjs的绝对路径 time.sleep(2) driver.get(url) browser.get(url) return url def get_total_page(url): total = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '#web-content > div > div.container-left > div.search-block > div.result-footer > div:nth-child(1) > ul > li:nth-child(11) > a'))) get_company_info() return total.text def login(): try: userInput = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '#web-content > div > div > div > div.position-rel.container.company_container > div > div.in-block.vertical-top.float-right.right_content.mt50.mr5.mb5 > div.module.module1.module2.loginmodule.collapse.in > div.modulein.modulein1.mobile_box.pl30.pr30.f14.collapse.in > div.pb30.position-rel > input'))) passwordInput = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'#web-content > div > div > div > div.position-rel.container.company_container > div > div.in-block.vertical-top.float-right.right_content.mt50.mr5.mb5 > div.module.module1.module2.loginmodule.collapse.in > div.modulein.modulein1.mobile_box.pl30.pr30.f14.collapse.in > div.pb40.position-rel > input'))) userInput.send_keys('15995028879') passwordInput.send_keys('19981027lcy') changeLoginWay = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'#web-content > div > div > div > div.position-rel.container.company_container > div > div.in-block.vertical-top.float-right.right_content.mt50.mr5.mb5 > div.module.module1.module2.loginmodule.collapse.in > div.modulein.modulein1.mobile_box.pl30.pr30.f14.collapse.in > div.c-white.b-c9.pt8.f18.text-center.login_btn'))) changeLoginWay.click() except TimeoutException: login() def get_company_info(): wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.search-block .result-list .search-result-single'))) html = browser.page_source doc = pq(html) items = doc('.search-block .result-list .search-result-single').items() for item in items: company = { 'urlInfo':item.find('.name ').attr('href'), 'name' : item.find('.name').text(), 'LegalRepresentative':item.find('.info .title a').text(), 'registerMoney':item.find('.info .title span').eq(0).text(), 'registerTime':item.find('.info .title span').eq(1).text(), 'tel':item.find('.contact .link-hover-click').eq(0).text(), 'email':item.find('.contact .link-hover-click').eq(1).text(), 'LegalPersonInfo':item.find('.content .match span').eq(1).text() } save_to_mongo(company) def next_page(page_number): print('------------------------------------正在爬取',page_number,'页-----------------------------------------------------------------') try: if page_number == 2: closeAdvertisement = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'#tyc_banner_close'))) closeAdvertisement.click() move_to_bottom() if page_number == 2: nextPageButton = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'#web-content > div > div.container-left > div.search-block > div.result-footer > div:nth-child(1) > ul > li:nth-child(12) > a'))) nextPageButton.click() if page_number > 2: nextPageButton = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'#web-content > div > div.container-left > div.search-block > div.result-footer > div:nth-child(1) > ul > li:nth-child(13) > a'))) nextPageButton.click() get_company_info() time.sleep(3) except TimeoutException: next_page(page_number) def save_to_mongo(result): if classname.insert(result): print('存储到mongoDB成功',result) else: print('存储到mongoDb失败') def main(): keyword = '阿里巴巴' url = search(keyword) login() total_pages = int(get_total_page(url)[-3:])#获取下他的总页数,但是没用,因为不是vip只能爬5页,本来我不是想吧下面那个6换成total_pages 的 for page in range(2,6): next_page(page) browser.close() if __name__ == '__main__': main()

目前的我的模拟登录不是最好的,还有种是直接利用登录后的cookies信息,用selenuim登录后直接就是已经登陆的状态,目前我还不怎么清楚怎么做,希望有大神在评论区说说。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有