selenium+Excel半自动化爬虫答题

10 篇文章 1 订阅

selenium+Excel半自动化搜索答案

1. 背景


上一篇文章中我们介绍了如何使用ChromeDriverManager 来管理ChromeDriver
如何使用ChromeDriverManager 来管理ChromeDriver_friklogff的博客-CSDN博客
本篇文章着重记录爬虫解析与学习过程,测试数据收集与结果处理下一篇我们再说。

请注意,本文中的部分内容来自网络搜集和个人实践,如有任何错误,请随时向我们提出批评和指正。本文仅供学习和交流使用,不涉及任何商业目的。如果因本文内容引发版权或侵权问题,请通过私信告知我们,我们将立即予以删除。

2. 技术选择

  • 使用Selenium控制Chrome浏览器爬取动态网页
  • 使用BeautifulSoup解析HTML
  • 使用OpenPyXL和XlsxWriter处理Excel文件

3. 实现过程

  1. 初始化ChromeDriver,使用ChromeDriverManager自动下载匹配chromedriver
  2. 实现一个get_answer方法
    • 输入搜索题目
    • 等待页面加载
    • 使用BeautifulSoup解析页面
    • 提取题目、答案、图片URL
  3. 读取Excel获取题目
  4. 调用get_answer获取每个题目的结果
  5. 将结果写入结果Excel

3.1 初始化ChromeDriver

使用ChromeDriverManager可以自动下载匹配Chrome版本的chromedriver,非常方便。

from webdriver_manager.chrome import ChromeDriverManager

driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))

3.2 实现获取答案方法

def get_answer(question):
    # 搜索题目
    search_input.send_keys(question) 
    search_btn.click()
    
    # 等待页面加载完成
    WebDriverWait(driver, 10).until()  
    
    # 解析页面
    soup = BeautifulSoup(driver.page_source, 'html.parser')  
    
    # 使用CSS选择器提取题目、答案
    question = soup.select('.question')
    answer = soup.select('.answer')
    
    # 返回结果
    return question, answer

这里使用CSS选择器提取信息,并使用WebDriverWait来等待页面元素加载。

3.3 读取Excel获取题目

使用openpyxl库读取Excel文件。

wb = openpyxl.load_workbook('questions.xlsx')
sheet = wb['Sheet1']
questions = [cell.value for cell in sheet['A']] 

3.4 保存结果到Excel

使用xlsxwriter库创建新的Excel文件,并逐行写入结果。

workbook = xlsxwriter.Workbook('results.xlsx')
worksheet = workbook.add_worksheet()

for idx, qa in enumerate(question_answers):
    worksheet.write(idx, 0, qa[0]) 
    worksheet.write(idx, 1, qa[1])
    
workbook.close()

3.5 主要流程

# 初始化
driver = init_driver()

# 读取题目
questions = read_excel() 

# 遍历爬取
results = []
for q in questions:
    result = get_answer(q)
    results.append(result)

# 保存结果  
save_to_excel(results)

4. 关键点

  • Selenium等待页面元素加载非常重要,这里使用WebDriverWait
  • 使用CSS选择器提取信息,BeautifulSoup find方法
  • Excel文件读写可以大批量处理题目
# -*- coding = utf-8 -*-
"""
# @Time : 2023/7/23 17:26
# @Author : FriK_log_ff 374591069
# @File : pc.py
# @Software: PyCharm
# @Function: 请输入项目功能
"""
import os
import time

import openpyxl
import xlsxwriter
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from webdriver_manager.chrome import ChromeDriverManager
from bs4 import BeautifulSoup

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



class AnswerScraper:

    def __init__(self):
        # 添加无头模式选项
        # options = Options()
        # options.add_argument("--headless")
        # 获取当前文件所在目录的绝对路径
        current_dir = os.path.dirname(os.path.abspath(__file__))
        # 设置驱动下载目录为当前目录下的drivers文件夹
        driver_path = os.path.join(current_dir, 'drivers')
        # 创建目录 如果存在则跳过创建
        os.makedirs(driver_path, exist_ok=True)
        # 初始化driver,使用ChromeDriverManager下载匹配Chrome版本的驱动
        self.driver = webdriver.Chrome(service=Service(ChromeDriverManager(path=driver_path).install()))
        # 简单的测试用例
        self.driver.get("https://tiku.baidu.com/buguakewap/browse/index?qid=undefined&limitSwitch=1&limitTimes=3")
        # 初始化WebDriverWait对象,用于等待页面元素加载,等待10秒,等页面加载元素
        self.wait = WebDriverWait(self.driver, 10)

    def get_answer(self, search_question):
        # 搜索问题
        search_input = self.driver.find_element(By.CSS_SELECTOR,
                "body > div.container-index > div.header > div > div.search > input[type=text]")
        # 定位搜索框
        search_input.click()

        search_input.clear()
        search_input.send_keys(search_question)
        # 在搜索框输入搜索词

        search_btn = self.driver.find_element(By.CSS_SELECTOR,
                                              "body > div.container-index > div.header > div > div.search > div")
        # 定位搜索按钮
        search_btn.click()
        # 等待页面加载
        self.wait = WebDriverWait(self.driver, 10)
        self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,
                                                        "body > div.container-index > div.main > div.content > div.quest > div.stem > div > p:nth-child(1) > span")))
        # 解析答案
        # htmls = self.driver.page_source
        quests = self.driver.find_elements(By.CSS_SELECTOR, ".quest")
        htmls = ''
        questions = ''
        answers = ''
        img_urls = ''
        for quest in quests:
            html = quest.get_attribute('outerHTML')
            htmls += html
            soup = BeautifulSoup(htmls, 'html.parser')
            # 提取问题
            question = soup.find('div', class_='stem__content').text
            questions += question
            # 提取答案
            answer = soup.find('div', class_='answer__content').text
            answers += answer
            # 提取图片
            try:
                img_url = soup.find('img').get('src')
                img_urls += img_url
                # img_urls.append(img_url)
            except:
                pass
        time.sleep(4)
        return [questions, answers, img_urls]


question_file = 'questions.xlsx'
result_file = 'results.xlsx'

# 读取题目
wb = openpyxl.load_workbook(question_file)
sheet = wb['Sheet1']
s_questions = [cell.value for cell in sheet['A'][1:]]
print(s_questions)
# 创建结果文件对象

workbook = xlsxwriter.Workbook(result_file)
worksheet = workbook.add_worksheet()

# 写入题目和答案
i = 0
for que in s_questions:
    i += 1
    scraper = AnswerScraper()
    print(f'正在获取题目"{que}\n"')
    result = scraper.get_answer(que)
    print(f'正在写入题目"{result[0]}"的答案"{result[1]}{result[2]}\n"')
    worksheet.write(i, 0, result[0])
    worksheet.write(i, 1, result[1])
    worksheet.write(i, 2, result[2])


workbook.close()

2023-08-31
最近chrome自动更新了116版本,chromedriver仍停留在114版本,以上代码会在当前目录自动下载最新版本chromedriver,只有当二者同步更新时可以正常使用

新文已发,完美解决二者未同步更新时产生的问题
自动化管理chromedriver-完美解决版本不匹配问题

国内使用chromedriver_autoinstaller网络受限,你可以在这里下载我下载好的chromedriver
链接:https://pan.baidu.com/s/1GnJTPO-4JPB_j2wrYZZJ8A?pwd=97jn
提取码:97jn
然后使用

service = Service("drivers/104/chromedriver.exe")

————————————————
版权声明:本文为CSDN博主「friklogff」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_42531954/article/details/132613060


import os
import time

import openpyxl
import requests
import xlsxwriter
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from webdriver_manager.chrome import ChromeDriverManager
from bs4 import BeautifulSoup

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



class AnswerScraper:

    def __init__(self):
        # 添加无头模式选项
        # options = Options()
        # options.add_argument("--headless")
        # 获取当前文件所在目录的绝对路径
        current_dir = os.path.dirname(os.path.abspath(__file__))
        # 设置驱动下载目录为当前目录下的drivers文件夹
        driver_path = os.path.join(current_dir, 'drivers')
        # 创建目录 如果存在则跳过创建
        os.makedirs(driver_path, exist_ok=True)
        # 初始化driver,使用ChromeDriverManager下载匹配Chrome版本的驱动
        # self.driver = webdriver.Chrome(service=Service(ChromeDriverManager(path=driver_path).install()))
        option = Options()
        option.add_experimental_option('excludeSwitches', ['enable-automation'])
        option.add_argument('--disable-blink-features=AutomationControlled')
        option.add_argument('--headless')  # 启用无头模式
        service = Service("drivers/104/chromedriver.exe")

        self.driver = webdriver.Chrome(options=option, service=service)
        # 简单的测试用例
        self.driver.get("https://tiku.baidu.com/buguakewap/browse/index?qid=undefined&limitSwitch=1&limitTimes=3")
        # 初始化WebDriverWait对象,用于等待页面元素加载,等待10秒,等页面加载元素
        self.wait = WebDriverWait(self.driver, 10)

    def get_answer(self, search_question):
        # 搜索问题
        search_input = self.driver.find_element(By.CSS_SELECTOR,
                "body > div.container-index > div.header > div > div.search > input[type=text]")
        # 定位搜索框
        search_input.click()

        search_input.clear()
        search_input.send_keys(search_question)
        # 在搜索框输入搜索词

        search_btn = self.driver.find_element(By.CSS_SELECTOR,
                                              "body > div.container-index > div.header > div > div.search > div")
        # 定位搜索按钮
        search_btn.click()
        # 等待页面加载
        self.wait = WebDriverWait(self.driver, 10)
        self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,
                                                        "body > div.container-index > div.main > div.content > div.quest > div.stem > div > p:nth-child(1) > span")))
        # 解析答案
        # htmls = self.driver.page_source
        quests = self.driver.find_elements(By.CSS_SELECTOR, ".quest")
        htmls = ''
        questions = ''
        answers = ''
        img_urls = ''
        for quest in quests:
            html = quest.get_attribute('outerHTML')
            htmls += html
            soup = BeautifulSoup(htmls, 'html.parser')
            # 提取问题
            question = soup.find('div', class_='stem__content').text
            questions += question
            # 提取答案
            answer = soup.find('div', class_='answer__content').text
            answers += answer
            # 提取图片
            try:
                img_url = soup.find('img').get('src')
                img_urls += img_url
                # img_urls.append(img_url)
            except:
                pass
        time.sleep(4)
        return [questions, answers, img_urls]


question_file = 'questions.xlsx'
result_file = 'results.xlsx'

# 读取题目
wb = openpyxl.load_workbook(question_file)
sheet = wb['Sheet1']
s_questions = [cell.value for cell in sheet['A'][1:]]
print(s_questions)
# 创建结果文件对象

workbook = xlsxwriter.Workbook(result_file)
worksheet = workbook.add_worksheet()

# 写入题目和答案
i = 0

for que in s_questions:
    i += 1
    scraper = AnswerScraper()
    print(f'正在获取题目"{que}\n"')
    result = scraper.get_answer(que)
    print(f'正在写入题目"{result[0]}"的答案"{result[1]}{result[2]}\n"')
    worksheet.write(i, 0, result[0])
    worksheet.write(i, 1, result[1])
    worksheet.write(i, 2, result[2])
#
#
workbook.close()

在这里插入图片描述

question_file = ‘questions.xlsx’

在这里插入图片描述

result_file = ‘results.xlsx’
在这里插入图片描述

5. 总结

通过这个爬虫项目,掌握了如下技能:

  • Selenium爬取动态网页
  • BeautifulSoup解析HTML
  • Excel文件读写
  • 项目规划和框架设计
  • 多种技术的组合运用
    下一次我们来尝试批量格式化提取问题,更合理的进行测试数据收集与结果处理,
    然后还可以考虑使用代理,多线程,数据库接入接入大语言模型等技术提高爬取效率和数据存储。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

friklogff

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值