最近接了個(gè)小項(xiàng)目需要批量搜索企查查上的相關(guān)企業(yè)并把指定信息保存到Excel文件中,由于企查查需要登錄后才能查看所有搜索到的信息所以第一步需要模擬登錄企查查。
python模擬登錄企查查最重要的是自動(dòng)拖拽驗(yàn)證插件
先介紹下項(xiàng)目中使用到的工具與庫(kù)
Python的selenium庫(kù):
Web應(yīng)用程序測(cè)試的工具,Selenium可以模擬用戶在瀏覽器中的操作,就像真實(shí)用戶使用一樣。
官方技術(shù)文檔:https://www.selenium.dev/selenium/docs/api/py/index.html
Chrome瀏覽器:
谷歌瀏覽器,不作過(guò)多介紹
Chromedriver:
配合Selenium操作Chrome瀏覽器的驅(qū)動(dòng)程序,注意在下載Chromedriver時(shí)必須與已安裝的Chrome瀏覽器版本號(hào)前3位保持一至
官方下載地址:http://chromedriver.storage.googleapis.com/index.html
獲取完整項(xiàng)目代碼請(qǐng)關(guān)注下面的公眾號(hào)“python客棧”然后回復(fù)“qcc”
第一步:下載配置Chromedriver
假設(shè)電腦中已安裝Chrome最新版(如果沒有安裝請(qǐng)自行下載安裝),下載與電腦系統(tǒng)、Chrome版本相匹配的版本(Chromedriver的版本號(hào)必須與安裝的Chrome版本號(hào)一至)。
從官網(wǎng)下載的文件是一個(gè)壓縮包,解壓出Chromedriver.exe文件,
網(wǎng)上有很多文章說(shuō)要正常使用Chromedriver.exe,需要配置系統(tǒng)的環(huán)境變量,其實(shí)這是一種比較麻煩的方法。
為了項(xiàng)目的可移動(dòng)性和操作方便使用另一種方法,就是把Chrome瀏覽器安裝目錄下的整個(gè)Application目錄都復(fù)制到項(xiàng)目目錄下,這樣就可以隨便移動(dòng)項(xiàng)目到新開發(fā)環(huán)境中而不用考慮新環(huán)境的系統(tǒng)環(huán)境變量了。
把解壓出Chromedriver.exe文件復(fù)制到項(xiàng)目目錄下的從Chrome瀏覽器安裝目錄中復(fù)制過(guò)來(lái)的Application目錄下,保證Chromedriver.exe文件與chrome.exe文件在同一目錄下。
第二步:安裝selenium庫(kù)
pip安裝selenium庫(kù)
pip install selenium
Pycharm開發(fā)工具安裝selenium庫(kù)
在Pycharm菜單欄中找到并點(diǎn)擊【file】->【settings】
在彈出窗口中按下圖所示操作
第三步:自動(dòng)模擬登錄企查查python代碼編寫
首先引入selenium相關(guān)庫(kù)
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基本配置參數(shù)
options = webdriver.ChromeOptions()
# options.add_argument('--headless') # 開啟無(wú)界面模式
options.add_argument('--disable-gpu') # 禁用gpu,解決一些莫名的問(wèn)題
options.add_argument('blink-settings=imagesEnabled=false') # 不加載圖片, 提升速度
options.add_argument('--disable-infobars') # 禁用瀏覽器正在被自動(dòng)化程序控制的提示
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必須參數(shù)
driver = webdriver.Chrome(options=options, executable_path="Application/chromedriver.exe", desired_capabilities=d)
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {#清除驗(yàn)證插件中windows.navigator.webdriver的值
"source": """
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
})
"""
})
模擬用戶在頁(yè)面中的一系列操作
driver.implicitly_wait(2)#延時(shí)
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"]'))
# 找到賬號(hào)輸入框
driver.find_element_by_xpath('//input[@id="nameVerify"]').send_keys('手機(jī)號(hào)')
自動(dòng)拖動(dòng)驗(yàn)證插件滑塊并驗(yàn)證
驗(yàn)證插件會(huì)檢測(cè)瀏覽器是否為webdriver即使用JS檢查windows.navigator.webdriver值
所以需要在頁(yè)面加載前手動(dòng)修改windows.navigator.webdriver值
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
"source": """
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
})
"""
})
修改完成windows.navigator.webdriver值后再模擬拖動(dòng)驗(yàn)證插件滑塊
# 滑動(dòng)條定位
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()
檢查驗(yàn)證是否成功
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', '請(qǐng)手工驗(yàn)證')
except:
tr = driver.find_element_by_xpath('//span[@class="nc-lang-cnt"][1]')
if tr.text != '驗(yàn)證通過(guò)':
set_id_att(driver, 'tt', 'innerHTML', '請(qǐng)手工驗(yàn)證')
# for i in range(1, 6):
# if tr.text == '驗(yàn)證通過(guò)':
# 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', '請(qǐng)?zhí)钊胧謾C(jī)驗(yàn)證碼')
# 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)
上面的代碼中在頁(yè)面里增加了一些狀態(tài)顯示元素及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訪問(wèn)頁(yè)面元素寫成函數(shù)方便以后操作
def set_id_att(bor, id, att, val):
bor.execute_script('document.getElementById("{a}").="{c}"'.format(a=id, b=att, c=val))
def set_class_att(bor, classs, id, att, val):
bor.execute_script('document.getElementsByClassName("{a}")[2wcsi0u].="{c}"'.format(a=classs, b=att, c=val, d=id))
登錄成功后還需要獲取頁(yè)面的headers、Cookie方便后面的requests庫(kù)使用
selenium獲取頁(yè)面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獲取頁(yè)面登錄后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}").="{c}"'.format(a=id, b=att, c=val))
def set_class_att(bor, classs, id, att, val):
bor.execute_script('document.getElementsByClassName("{a}")[omq0ikm].="{c}"'.format(a=classs, b=att, c=val, d=id))
def login():
options = webdriver.ChromeOptions()
# options.add_argument('--headless') # 開啟無(wú)界面模式
options.add_argument('--disable-gpu') # 禁用gpu,解決一些莫名的問(wèn)題
options.add_argument('blink-settings=imagesEnabled=false') # 不加載圖片, 提升速度
options.add_argument('--disable-infobars') # 禁用瀏覽器正在被自動(dòng)化程序控制的提示
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"]'))
# 找到賬號(hào)輸入框
driver.find_element_by_xpath('//input[@id="nameVerify"]').send_keys('19942496979')
# 滑動(dòng)條定位
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', '請(qǐng)手工驗(yàn)證')
except:
tr = driver.find_element_by_xpath('//span[@class="nc-lang-cnt"][1]')
if tr.text != '驗(yàn)證通過(guò)':
set_id_att(driver, 'tt', 'innerHTML', '請(qǐng)手工驗(yàn)證')
# for i in range(1, 6):
# if tr.text == '驗(yàn)證通過(guò)':
# 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', '請(qǐng)?zhí)钊胧謾C(jī)驗(yàn)證碼')
# 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()#自動(dòng)登錄并獲取登錄后的Headers包括cookies
要獲取完整項(xiàng)目代碼(selenium模擬登錄企查查+requests庫(kù)自動(dòng)搜索獲取指定信息并保存Excel)請(qǐng)關(guān)注上面的公眾號(hào)“python客棧”然后回復(fù)“qcc”
本文主要介紹了如何使用python的selenium模擬登錄企查查,主要介紹了如何使用selenium保存Cookies與headers、自動(dòng)驗(yàn)證及selenium庫(kù)對(duì)頁(yè)面元素的一些操作方法
下一篇將介紹Python使用requests庫(kù)自動(dòng)在企查查上搜索相關(guān)企業(yè)并獲取指定信息
您可能感興趣的文章:- python爬蟲利用selenium實(shí)現(xiàn)自動(dòng)翻頁(yè)爬取某魚數(shù)據(jù)的思路詳解
- Python selenium爬取微博數(shù)據(jù)代碼實(shí)例
- Python進(jìn)階之使用selenium爬取淘寶商品信息功能示例
- python selenium爬取斗魚所有直播房間信息過(guò)程詳解
- Python使用Selenium+BeautifulSoup爬取淘寶搜索頁(yè)
- python爬蟲系列Selenium定向爬取虎撲籃球圖片詳解
- Python爬蟲實(shí)戰(zhàn)之用selenium爬取某旅游網(wǎng)站