使用selenium爬取网页的时候,一直加载很久才执行

今天在使用selenium爬取 中国执行信息公开网的时候遇到了一个问题:

明明浏览器已经访问了,但是还是一直不进行下一步动作,而是一直在加载,在网上找了很多答案后,发现原来selemim会等网站的所有元素都加载完毕才会执行后面的操作,如此一来我们的程序就会一直阻塞相当长的一段时间,这显然不是我们想要的,那么该如何解决呢?

其实很简单!

使用set_page_load_timeout这个方法设置一个超时时间即可,代码如下:

from selenium import webdriver

browser = webdriver.Chrome() # 实例化一个浏览器对象
browser.set_page_load_timeout(5) # 设置超时时间为5秒,如果5秒后网页还是没有加载完成则抛出异常
try:
  browser.get(url) # 请求 url
except TimeoutException: # 捕获超时异常
  print("超时跳过")

这时可能会导致一个情况:就是超过了5秒我们自己想要处理定位的元素也没有加载出来怎么办?
我使用了selenium的显式等待带处理这个问题(其实不用也可以,直接捕获异常重新处理即可)

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

browser = webdriver.Chrome() # 实例化一个浏览器对象
browser.set_page_load_timeout(5) # 设置超时时间为5秒,如果5秒后网页还是没有加载完成则抛出异常
try:
  browser.get(url) # 请求 url
except TimeoutException: # 捕获超时异常
  print("超时跳过")

wait = WebDriverWait(browser, 6) # 设置显式等待对象,若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'))) # 定位验证码输入框

以下是这个方法的代码,这是其中爬取页面源码的部分,新手学习,仅供参考:

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初始设置为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")  # 当开始输入验证码时,验证码图片会刷新,所以先输入然后再清空,防止验证码图片改变,起到提前刷新一下验证码的作用
                input_captcha.clear()# 清空以便输入
                time.sleep(random.uniform(2.5, 2.8))
                self.save_captcha(browser)  # 截取验证码
                
                captcha_result = self.get_captcha_result() # 使用打码平台获取验证码的值
                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) # 将打码平台打好的验证码输入验证码框中
                time.sleep(random.uniform(1.5, 1.8)) # 延迟1.5到1.8秒,让网页反应一下
                button_search.click()  # 点击查询按钮
                time.sleep(random.uniform(1.5, 1.8))

                button_check = wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'View')))# 此时浏览器出现了查看按钮
                try:
                    button_check.click()  # 点击查看
                except TimeoutException:
                    print("超时跳过")
                time.sleep(random.uniform(3.5, 3.8))

                # 此时浏览器出现了第二个标签,我们想要的数据就在这个标签上,切换到第二个标签
                browser.switch_to.window(browser.window_handles[1])
                html_source = browser.page_source
                # 若成功
                flag = 1000 # 成功了将flag设为大于5的数即可,此时跳出while循环

            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) # 当爬取5次后失败时,把未爬取成功的数据存入表中,等待后续处理
                    print("获取失败,将url存入数据库")
                    # flag = 0
                time.sleep(flag) # 延迟一下,失败次数越多,延迟的时间越长
                html_source = None # 若五次均失败,则返回None

        browser.close()# 关闭网页
        browser.quit()# 关闭浏览器
        return html_source # 返回爬取的页面源码

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

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

            # 打开页面输入信息,点击查看按钮,获取当前页面源码
            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()
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容