Selenium
Selenium是一個(gè)模擬瀏覽器瀏覽網(wǎng)頁的工具,主要用于測試網(wǎng)站的自動(dòng)化測試工具。
Selenium需要安裝瀏覽器驅(qū)動(dòng),才能調(diào)用瀏覽器進(jìn)行自動(dòng)爬取或自動(dòng)化測試,常見的包括Chrome、Firefox、IE、PhantomJS等瀏覽器。
注意:驅(qū)動(dòng)下載解壓后,置于Python的安裝目錄下;然后將Python的安裝目錄添加到系統(tǒng)環(huán)境變量路徑(Path)中。
WebDriver 對(duì)象提供的相關(guān)方法
- close() 方法用于關(guān)閉單個(gè)窗口
- quit() 方法用于關(guān)閉所有窗口
- page_source 屬性用于獲取網(wǎng)頁的源代碼
- get(url) 方法用于訪問指定的 URL
- title 屬性用于獲取當(dāng)前頁面的標(biāo)題
- current_url 用于獲取當(dāng)前頁面的 URL
- set_window_size(idth,height) 方法用于設(shè)置瀏覽器的尺寸
- back() 方法用于控制瀏覽器后退
- forward() 方法用于控制瀏覽器前進(jìn)
- refresh() 方法用于刷新當(dāng)前頁面
定位元素
find_elements_by_css_selector("#kw") # 根據(jù)選擇器進(jìn)行定位查找,其中#kw表示的是id選擇器名稱是kw的
可以通過 WebElement 對(duì)象的相text 屬性用于獲取元素的文本內(nèi)容
import time
from selenium import webdriver
#啟動(dòng)瀏覽器,啟動(dòng)的是chrome瀏覽器,注意C是大寫的
# test_webdriver = webdriver.Chrome()
#調(diào)用的phantomjs瀏覽器
# test_webdriver = webdriver.PhantomJS()
#使用火狐瀏覽器
test_webdriver = webdriver.Firefox()
#通過get請(qǐng)求的方式請(qǐng)求https://www.echartsjs.com/examples/
test_webdriver.get("https://www.echartsjs.com/examples/")
#瀏覽器最大化窗口
test_webdriver.maximize_window()
#通過一個(gè)for循環(huán)來遍歷這些數(shù)據(jù)
#find_elements_by_xpath,注意,雙數(shù),方法里面?zhèn)鬟f的是xpath語句
for item in test_webdriver.find_elements_by_xpath("http://h4[@class='chart-title']"):
#獲取當(dāng)前節(jié)點(diǎn)的text
print(item.text)
#獲取當(dāng)前瀏覽器的標(biāo)題
print(test_webdriver.title)
time.sleep(5)
#瀏覽器退出
test_webdriver.quit()
ActionChains的基本使用
selenium.webdriver.common.action_chains.ActionChains(driver)
click(on_element=None) ——單擊鼠標(biāo)左鍵
click_and_hold(on_element=None) ——點(diǎn)擊鼠標(biāo)左鍵,不松開
context_click(on_element=None) ——點(diǎn)擊鼠標(biāo)右鍵
double_click(on_element=None) ——雙擊鼠標(biāo)左鍵
drag_and_drop(source, target) ——拖拽到某個(gè)元素然后松開
drag_and_drop_by_offset(source, xoffset, yoffset) ——拖拽到某個(gè)坐標(biāo)然后松開
key_down(value, element=None) ——按下某個(gè)鍵盤上的鍵
key_up(value, element=None) ——松開某個(gè)鍵
move_by_offset(xoffset, yoffset) ——鼠標(biāo)從當(dāng)前位置移動(dòng)到某個(gè)坐標(biāo)
move_to_element(to_element) ——鼠標(biāo)移動(dòng)到某個(gè)元素
move_to_element_with_offset(to_element, xoffset, yoffset) ——移動(dòng)到距某個(gè)元素(左上角坐標(biāo))多少距離的位置
perform() ——執(zhí)行鏈中的所有動(dòng)作
release(on_element=None) ——在某個(gè)元素位置松開鼠標(biāo)左鍵
send_keys(*keys_to_send) ——發(fā)送某個(gè)鍵到當(dāng)前焦點(diǎn)的元素
send_keys_to_element(element, *keys_to_send) ——發(fā)送某個(gè)鍵到指定元素
from selenium import webdriver
import time
test_webdriver = webdriver.Chrome()
test_webdriver.maximize_window()
test_webdriver.get("https://www.baidu.com")
#找到百度首頁上的搜索框,發(fā)送python
test_webdriver.find_element_by_xpath("http://input[@id='kw']").send_keys("python")
#找到百度一下這個(gè)按鈕,點(diǎn)擊一下
test_webdriver.find_element_by_xpath("http://input[@id='su']").click()
time.sleep(5)
print(test_webdriver.title)
#獲取當(dāng)前頁面的源代碼
print(test_webdriver.page_source)
#獲取當(dāng)前的cookie
print(test_webdriver.get_cookies())
test_webdriver.quit()
selenium顯示等待和隱式等待
顯示等待
明確要等到某個(gè)元素的出現(xiàn)或者是某個(gè)元素的可點(diǎn)擊等條件,等不到,就一直等,除非在規(guī)定的時(shí)間之內(nèi)都沒找到,就會(huì)跳出異常Exception。
WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)
WebDriverWait()一般由until()或 until_not()方法配合使用
-
until(method, message=’ '):調(diào)用該方法提供的驅(qū)動(dòng)程序作為一個(gè)參數(shù),直到返回值為True
-
until_not(method, message=’ '):調(diào)用該方法提供的驅(qū)動(dòng)程序作為一個(gè)參數(shù),直到返回值為False
隱式等待
在創(chuàng)建driver時(shí),為瀏覽器對(duì)象創(chuàng)建一個(gè)等待時(shí)間,這個(gè)方法是得不到某個(gè)元素就等待一段時(shí)間,直到拿到某個(gè)元素位置。
注意:在使用隱式等待的時(shí)候,實(shí)際上瀏覽器會(huì)在你自己設(shè)定的時(shí)間內(nèi)部斷的刷新頁面去尋找我們需要的元素
driver.implicitly_wait()
默認(rèn)設(shè)置為0
#顯示等待
# from selenium import webdriver
# #簡寫用包
# from selenium.webdriver.common.by import By
# #等待用包
# from selenium.webdriver.support.ui import WebDriverWait
# #場景判斷,用來判斷某個(gè)元素是否出現(xiàn)
# from selenium.webdriver.support import expected_conditions as EC
# import time
#
#
# test_driver = webdriver.Chrome()
# test_driver.maximize_window()
# test_driver.get("https://www.baidu.com")
# #WebDriverWait設(shè)置顯示等待
# #1、test_driver,2、timeout,3、輪訓(xùn)參數(shù)
# #until,EC場景判斷,通過id來找相關(guān)元素kw
# element = WebDriverWait(test_driver,5,0.5).until(EC.presence_of_element_located((By.ID,'dazhuang')))
# element.send_keys('python')
# time.sleep(2)
# test_driver.quit()
#隱式等待
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
import time
test_driver = webdriver.Chrome()
test_driver.implicitly_wait(5)
test_driver.get("https://www.baidu.com")
try:
test_driver.find_element_by_id('dazhuang').send_keys('python')
time.sleep(2)
except NoSuchElementException as e:
print('這里報(bào)錯(cuò)了')
print(e)
test_driver.quit()
Chrome無界面瀏覽器
之前所應(yīng)用的 Selenium,都是直接操作有界面的瀏覽器,這就勢必會(huì)影響爬取數(shù)據(jù)的速度,而為了盡可能地提高爬取數(shù)據(jù)的速度,則可以使用 Chrome 無界面瀏覽器進(jìn)行數(shù)據(jù)的爬取,其步驟如下:
- 首先,通過 selenium.webdriver.chrome.options 中的 Options 類創(chuàng)建 Options
對(duì)象,用于操作 Chrome 無界面瀏覽器。 - 其次,使用 Options 對(duì)象的 add_argument() 方法啟動(dòng)參數(shù)配置,并將該方法中的參數(shù) argument 的值設(shè)置為“—headless”,表示使用無界面瀏覽器。
- 最后,在使用 Chrome 類創(chuàng)建 WebDriver 對(duì)象時(shí)設(shè)置參數(shù) options,并且該參數(shù)對(duì)應(yīng)的值需為之前所創(chuàng)建的
Options 對(duì)象。
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import time
# 實(shí)例化參數(shù)的方法
chrome_options = Options()
# 設(shè)置瀏覽器的無頭瀏覽器,無界面,瀏覽器將不提供界面,linux操作系統(tǒng)無界面情況下就可以運(yùn)行了
chrome_options.add_argument("--headless")
# 結(jié)果devtoolsactiveport文件不存在的報(bào)錯(cuò)
chrome_options.add_argument("--no-sandbox")
# 官方推薦的關(guān)閉選項(xiàng),規(guī)避一些BUG
chrome_options.add_argument("--disable-gpu")
# 實(shí)例化了一個(gè)chrome,導(dǎo)入設(shè)置項(xiàng)
test_webdriver = webdriver.Chrome(options=chrome_options)
# 最大化
test_webdriver.maximize_window()
# 打開百度
test_webdriver.get("https://www.baidu.com")
# 再輸入框里面輸入了python
test_webdriver.find_element_by_xpath("http://input[@id='kw']").send_keys("python")
# 執(zhí)行了點(diǎn)擊操作
test_webdriver.find_element_by_xpath("http://input[@id='su']").click()
time.sleep(2)
# 打印web界面的title
print(test_webdriver.title)
# 瀏覽器退出
test_webdriver.quit()
Scrapy(異步網(wǎng)絡(luò)爬蟲框架)
Scrapy框架
各組件的作用
Scrapy Engine
- 引擎負(fù)責(zé)控制數(shù)據(jù)流在系統(tǒng)中所有組件中流動(dòng),并在相應(yīng)動(dòng)作發(fā)生時(shí)觸發(fā)事件。 詳細(xì)內(nèi)容查看下面的數(shù)據(jù)流(Data Flow)部分。
- 此組件相當(dāng)于爬蟲的“大腦”,是整個(gè)爬蟲的調(diào)度中心。
調(diào)度器(Scheduler)
- 調(diào)度器從引擎接受request并將他們?nèi)腙?duì),以便之后引擎請(qǐng)求他們時(shí)提供給引擎。
- 初始的爬取URL和后續(xù)在頁面中獲取的待爬取的URL將放入調(diào)度器中,等待爬取。同時(shí)調(diào)度器會(huì)自動(dòng)去除重復(fù)的URL(如果特定的URL不需要去重也可以通過設(shè)置實(shí)現(xiàn),如post請(qǐng)求的URL)
下載器(Downloader)
- 下載器負(fù)責(zé)獲取頁面數(shù)據(jù)并提供給引擎,而后提供給spider。
Spiders
- Spider是Scrapy用戶編寫用于分析response并提取item(即獲取到的item)或額外跟進(jìn)的URL的類。
每個(gè)spider負(fù)責(zé)處理一個(gè)特定(或一些)網(wǎng)站。
Item Pipeline
-
Item Pipeline負(fù)責(zé)處理被spider提取出來的item。典型的處理有清理、 驗(yàn)證及持久化(例如存取到數(shù)據(jù)庫中)。
-
當(dāng)頁面被爬蟲解析所需的數(shù)據(jù)存入Item后,將被發(fā)送到項(xiàng)目管道(Pipeline),并經(jīng)過幾個(gè)特定的次序處理數(shù)據(jù),最后存入本地文件或存入數(shù)據(jù)庫。
下載器中間件(Downloader middlewares)
-
下載器中間件是在引擎及下載器之間的特定鉤子(specific hook),處理Downloader傳遞給引擎的response。
-
其提供了一個(gè)簡便的機(jī)制,通過插入自定義代碼來擴(kuò)展Scrapy功能。
-
通過設(shè)置下載器中間件可以實(shí)現(xiàn)爬蟲自動(dòng)更換user-agent、IP等功能。
Spider中間件(Spider middlewares)
-
Spider中間件是在引擎及Spider之間的特定鉤子(specific
hook),處理spider的輸入(response)和輸出(items及requests)。 -
其提供了一個(gè)簡便的機(jī)制,通過插入自定義代碼來擴(kuò)展Scrapy功能。
常見的創(chuàng)建scrapy語句:
scrapy startproject 項(xiàng)目名
scrapy genspider 爬蟲名 域名
scrapy crawl 爬蟲名
scrapy.cfg 項(xiàng)目的主配置信息。(真正爬蟲相關(guān)的配置信息在settings.py文件中)
items.py 設(shè)置數(shù)據(jù)存儲(chǔ)模板,用于結(jié)構(gòu)化數(shù)據(jù),如:Django的Model
pipelines 數(shù)據(jù)持久化處理
settings.py 配置文件
spiders 爬蟲目錄
參考:https://scrapy-chs.readthedocs.io/zh_CN/latest/intro/overview.html
參考:https://www.osgeo.cn/scrapy/topics/architecture.html
反爬蟲
限制爬蟲程序訪問服務(wù)器資源和獲取數(shù)據(jù)的行為
限制手段
請(qǐng)求限制、拒絕響應(yīng)、客戶端身份驗(yàn)證、文本混淆和使用動(dòng)態(tài)渲染技術(shù)等
反爬蟲的分類
身份識(shí)別反爬蟲
- 驗(yàn)證請(qǐng)求頭信息、驗(yàn)證請(qǐng)求參數(shù)、使用驗(yàn)證碼等
爬蟲行為反爬蟲
- 對(duì)ip進(jìn)行限制、使用蜜罐獲取ip、假數(shù)據(jù)等
數(shù)據(jù)加密反爬蟲
- 自定義字體、數(shù)據(jù)圖片、編碼格式等
爬蟲與反爬蟲-功與防
基于身份識(shí)別反爬和結(jié)局思路
Headers反爬-通過User-agent字段
攜帶正確的User-agent和使用隨機(jī)User-agent
Headers反爬-通過cookie字段
注冊(cè)多個(gè)賬號(hào)請(qǐng)求登錄后數(shù)據(jù)或破解JS生成cookie邏輯
Headers反爬-通過Referer字段
偽造Referer字段
基于請(qǐng)求參數(shù)反爬
仔細(xì)分析抓到的包,搞清楚請(qǐng)求之間的聯(lián)系
驗(yàn)證碼反爬
Pytesseract/商業(yè)打碼平臺(tái)
驗(yàn)證碼(CAPTCHA)是“Completely Automated Public Turing testto tell Computers and Humans Apart”(全自動(dòng)區(qū)分計(jì)算機(jī)和人類的圖靈測試)的縮寫,是一種區(qū)分用戶是計(jì)算機(jī)還是人的公共全自動(dòng)程序。
基于爬蟲行為反爬和解決思路
通過請(qǐng)求ip/賬號(hào)單位時(shí)間內(nèi)請(qǐng)求頻率、次數(shù)反爬
使用ip代理、多個(gè)賬號(hào)反反爬
通過同一ip/賬號(hào)請(qǐng)求間隔進(jìn)行反爬
使用ip代理,設(shè)置隨機(jī)休眠進(jìn)行反反爬
通過js實(shí)現(xiàn)跳轉(zhuǎn)反爬
多次抓包,分析規(guī)律
通過蜜罐(陷阱)捕獲ip
完成爬蟲之后,測試爬取/仔細(xì)分析相應(yīng)內(nèi)容,找出陷阱
通過假數(shù)據(jù)進(jìn)行反爬
長期運(yùn)行,對(duì)比數(shù)據(jù)庫中數(shù)據(jù)同實(shí)際頁面數(shù)據(jù)
阻塞任務(wù)隊(duì)列
分析獲取垃圾url的規(guī)律,對(duì)URL進(jìn)行過濾
阻塞網(wǎng)絡(luò)IO
審查抓取連接,對(duì)請(qǐng)求時(shí)間計(jì)時(shí)
基于數(shù)據(jù)加密反爬和解決思路
通過自定義字體反爬
切換到手機(jī)版/解析自定義字體
通過js動(dòng)態(tài)生成數(shù)據(jù)進(jìn)行反爬
分析js生成數(shù)據(jù)的流程,模擬生成數(shù)據(jù)
通過數(shù)據(jù)圖片化進(jìn)行反爬
通過使用圖片引擎,解析圖片數(shù)據(jù)文章來源:http://www.zghlxwxcb.cn/news/detail-801736.html
通過編碼格式進(jìn)行反爬
測試不同格式解碼,獲取正確的解碼格式文章來源地址http://www.zghlxwxcb.cn/news/detail-801736.html
到了這里,關(guān)于網(wǎng)絡(luò)爬蟲(Python:Selenium、Scrapy框架;爬蟲與反爬蟲筆記)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!