使用selenium爬取網(wǎng)頁的時候,一直加載很久才執(zhí)行

今天在使用selenium爬取 中國執(zhí)行信息公開網(wǎng)的時候遇到了一個問題:

明明瀏覽器已經(jīng)訪問了,但是還是一直不進(jìn)行下一步動作,而是一直在加載,在網(wǎng)上找了很多答案后,發(fā)現(xiàn)原來selemim會等網(wǎng)站的所有元素都加載完畢才會執(zhí)行后面的操作,如此一來我們的程序就會一直阻塞相當(dāng)長的一段時間,這顯然不是我們想要的,那么該如何解決呢?

其實(shí)很簡單!

使用set_page_load_timeout這個方法設(shè)置一個超時時間即可,代碼如下:

from selenium import webdriver

browser = webdriver.Chrome() # 實(shí)例化一個瀏覽器對象
browser.set_page_load_timeout(5) # 設(shè)置超時時間為5秒,如果5秒后網(wǎng)頁還是沒有加載完成則拋出異常
try:
  browser.get(url) # 請求 url
except TimeoutException: # 捕獲超時異常
  print("超時跳過")

這時可能會導(dǎo)致一個情況:就是超過了5秒我們自己想要處理定位的元素也沒有加載出來怎么辦?
我使用了selenium的顯式等待帶處理這個問題(其實(shí)不用也可以,直接捕獲異常重新處理即可)

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

browser = webdriver.Chrome() # 實(shí)例化一個瀏覽器對象
browser.set_page_load_timeout(5) # 設(shè)置超時時間為5秒,如果5秒后網(wǎng)頁還是沒有加載完成則拋出異常
try:
  browser.get(url) # 請求 url
except TimeoutException: # 捕獲超時異常
  print("超時跳過")

wait = WebDriverWait(browser, 6) # 設(shè)置顯式等待對象,若6秒還未加載出來則拋出異常
input_name = wait.until(EC.presence_of_element_located((By.ID, 'pName'))) # 定位姓名輸入框 
input_usr_id = wait.until(EC.presence_of_element_located((By.ID, 'pCardNum'))) # 定位證件號輸入框
input_captcha = wait.until(EC.presence_of_element_located((By.ID, 'yzm'))) # 定位驗(yàn)證碼輸入框

以下是這個方法的代碼,這是其中爬取頁面源碼的部分,新手學(xué)習(xí),僅供參考:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
from chaojiying_Python.chaojiying import Chaojiying_Client # 對接的是超級鷹打碼平臺
from PIL import Image
import time
import random
import pymysql
from lxml import etree
import csv
import json

class Zxgk_spider:
    def __init__(self, url, conn):
        self.url = url
        self.conn = conn

    def read_csv(self):
        '''
        讀取csv文件
        :return:
        '''
        l = []
        with open('name.csv') as f: # 這個文件是要爬取的人員名單
            reader = csv.reader(f)
            for row in reader:
                l.append(row)

        return l

    def post_content(self, name, usr_id):
        url = self.url
        browser = webdriver.Chrome()
        browser.maximize_window()  # 最大化瀏覽器
        im_id = 0 # 圖片id初始設(shè)置為0,這個是用來
        flag = 0
        while flag < 5:
            try:
                browser.set_page_load_timeout(5)
                try:
                    browser.get(url)
                except TimeoutException:
                    print("超時跳過")
                wait = WebDriverWait(browser, 6)
                input_name = wait.until(EC.presence_of_element_located((By.ID, 'pName')))
                input_usr_id = wait.until(EC.presence_of_element_located((By.ID, 'pCardNum')))
                input_captcha = wait.until(EC.presence_of_element_located((By.ID, 'yzm')))
                button_search = browser.find_element_by_class_name('btn.btn-zxgk.btn-block')
                input_name.clear()# 清空輸入框
                input_usr_id.clear()# 清空輸入框
                input_name.send_keys(name)
                input_usr_id.send_keys(usr_id)
                input_captcha.send_keys("1234")  # 當(dāng)開始輸入驗(yàn)證碼時,驗(yàn)證碼圖片會刷新,所以先輸入然后再清空,防止驗(yàn)證碼圖片改變,起到提前刷新一下驗(yàn)證碼的作用
                input_captcha.clear()# 清空以便輸入
                time.sleep(random.uniform(2.5, 2.8))
                self.save_captcha(browser)  # 截取驗(yàn)證碼
                
                captcha_result = self.get_captcha_result() # 使用打碼平臺獲取驗(yàn)證碼的值
                pic_str = captcha_result['pic_str']
                im_id = captcha_result['pic_id']
                print(pic_str)
                print(type(pic_str))
                input_captcha.send_keys(pic_str) # 將打碼平臺打好的驗(yàn)證碼輸入驗(yàn)證碼框中
                time.sleep(random.uniform(1.5, 1.8)) # 延遲1.5到1.8秒,讓網(wǎng)頁反應(yīng)一下
                button_search.click()  # 點(diǎn)擊查詢按鈕
                time.sleep(random.uniform(1.5, 1.8))

                button_check = wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'View')))# 此時瀏覽器出現(xiàn)了查看按鈕
                try:
                    button_check.click()  # 點(diǎn)擊查看
                except TimeoutException:
                    print("超時跳過")
                time.sleep(random.uniform(3.5, 3.8))

                # 此時瀏覽器出現(xiàn)了第二個標(biāo)簽,我們想要的數(shù)據(jù)就在這個標(biāo)簽上,切換到第二個標(biāo)簽
                browser.switch_to.window(browser.window_handles[1])
                html_source = browser.page_source
                # 若成功
                flag = 1000 # 成功了將flag設(shè)為大于5的數(shù)即可,此時跳出while循環(huán)

            except Exception as e:
                print("捕獲異常:{}".format(e))
                self.ReportError(im_id)
                flag += 1
                print("{}第{}次爬取失敗".format(name, flag))
                if flag >= 5:
                    self.insert_into_url_mysql(name, usr_id, flag) # 當(dāng)爬取5次后失敗時,把未爬取成功的數(shù)據(jù)存入表中,等待后續(xù)處理
                    print("獲取失敗,將url存入數(shù)據(jù)庫")
                    # flag = 0
                time.sleep(flag) # 延遲一下,失敗次數(shù)越多,延遲的時間越長
                html_source = None # 若五次均失敗,則返回None

        browser.close()# 關(guān)閉網(wǎng)頁
        browser.quit()# 關(guān)閉瀏覽器
        return html_source # 返回爬取的頁面源碼

    def run(self):
        # 獲取信息
        reader = self.read_csv()

        for row in reader:
            name = row[1]
            usr_id = row[3]

            # 打開頁面輸入信息,點(diǎn)擊查看按鈕,獲取當(dāng)前頁面源碼
            html_source = self.post_content(name, usr_id)
            if html_source == None:
                continue
            else:
                pass

if __name__ == '__main__':
    conn = pymysql.connect(
        host="127.0.0.1",
        port=3306,
        user="user",
        password="xxxx",
        database="database_name",
        charset="utf8"
    )
    url = "http://zxgk.court.gov.cn/zhzxgk/"
    zxgk = Zxgk_spider(url, conn)
    zxgk.run()
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容