AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / coding / 问题 / 79420323
Accepted
Moran Hanane
Moran Hanane
Asked: 2025-02-07 17:15:56 +0800 CST2025-02-07 17:15:56 +0800 CST 2025-02-07 17:15:56 +0800 CST

我如何抓取此 URL 的“详细信息”部分中的数据:https://gallica.bnf.fr/ark:/12148/cb42768809f/date?

  • 772

大家好,我是网络抓取方面的新手。

我正在尝试将此网页( https://gallica.bnf.fr/ark:/12148/cb42768809f/date )的“详细信息”部分中的数据进行网络抓取,以便能够使用其每个字段填充 SQL 数据库。

这是一个测试 URL。我通过该网站的 API 请求了一个包含 500 个类似 URL 的列表。我打算在 Python 函数运行后将其应用于此列表的所有 URL。

有什么建议可以帮助我从这个网页中提取我需要的信息吗?非常感谢!

首先,我尝试使用 beautifulsoup,但问题是只有单击下拉按钮时才会出现“详细信息”部分。

我尝试了几个漂亮的代码片段,比如下面的代码,但是没有起作用:

def get_metadata_bs4(url):
    response = requests.get(url)
    soup = BeautifulSoup(response.text, "html.parser")

    try:
        
        title = soup.find("h1").text.strip() if soup.find("h1") else "Titre inconnu"

        
        publisher = soup.select_one("dl dd:nth-of-type(1)").text.strip() if soup.select_one("dl dd:nth-of-type(1)") else "Auteur inconnu"

        
        Date of publication = soup.select_one("dl dd:nth-of-type(2)").text.strip() if soup.select_one("dl dd:nth-of-type(2)") else "Date inconnue"

        return {"title": title, "author": author, "Date of publication": Date of publication}
    
    except Exception as e:
        print(f"Erreur pour {url}: {e}")
        return None

# Tester avec un seul lien
url_test = "https://gallica.bnf.fr/ark:/12148/cb42768809f/date"
print(get_metadata_bs4(url_test))

因此我尝试了 selenium,但这是我第一次使用这个 Python 库...我尝试找到源代码的正确 X-Path,并在以下代码块中用这个 X-path 替换“metadata-class”:

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 selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time

# Configuration Selenium
chrome_options = Options()
chrome_options.add_argument("--headless")  # Mode sans interface graphique
driver = webdriver.Chrome(options=chrome_options)

def get_metadata_from_notice(url):
    driver.get(url)
    time.sleep(2)  # Laisser le temps de charger
    
    try:
        # Cliquer sur le dropdown "Informations détaillées"
        dropdown = WebDriverWait(driver, 5).until(
            EC.element_to_be_clickable((By.XPATH, "//div[contains(text(), 'Informations détaillées')]"))
        )
        dropdown.click()
        time.sleep(2)  # Attendre le chargement après le clic
    except Exception as e:
        print(f"⚠️ Erreur lors du clic sur {url} : {e}")
        return None

    try:
        # Extraction des métadonnées après ouverture du dropdown
        metadata_section = driver.find_element(By.XPATH, "//div[@class='metadata-class']")  # À remplacer par la bonne classe
        metadata_text = metadata_section.text
        return {"url": url, "metadata": metadata_text}
    except Exception as e:
        print(f"⚠️ Impossible de récupérer les métadonnées pour {url} : {e}")
        return None

# Test sur une URL
test_url = "https://gallica.bnf.fr/ark:/12148/cb42768809f/date"
print(get_metadata_from_notice(test_url))

# Fermer Selenium
driver.quit()

但它一直给我这样的结果:

⚠️ Impossible de récupérer les métadonnées pour https://gallica.bnf.fr/ark:/12148/cb42768809f/date
⚠️ Erreur sur https://gallica.bnf.fr/ark:/12148/cb452698066/date : Message: 
Stacktrace:
    GetHandleVerifier [0x00007FF7940A02F5+28725]
    (No symbol) [0x00007FF794002AE0]
    (No symbol) [0x00007FF793E9510A]
    (No symbol) [0x00007FF793EE93D2]
    (No symbol) [0x00007FF793EE95FC]
    (No symbol) [0x00007FF793F33407]
    (No symbol) [0x00007FF793F0FFEF]
    (No symbol) [0x00007FF793F30181]
    (No symbol) [0x00007FF793F0FD53]
    (No symbol) [0x00007FF793EDA0E3]
    (No symbol) [0x00007FF793EDB471]
    GetHandleVerifier [0x00007FF7943CF30D+3366989]
    GetHandleVerifier [0x00007FF7943E12F0+3440688]
    GetHandleVerifier [0x00007FF7943D78FD+3401277]
    GetHandleVerifier [0x00007FF79416AAAB+858091]
    (No symbol) [0x00007FF79400E74F]
    (No symbol) [0x00007FF79400A304]
    (No symbol) [0x00007FF79400A49D]
    (No symbol) [0x00007FF793FF8B69]
    BaseThreadInitThunk [0x00007FFC0A7D259D+29]
    RtlUserThreadStart [0x00007FFC0BA0AF38+40]
selenium-webdriver
  • 2 2 个回答
  • 61 Views

2 个回答

  • Voted
  1. iliak
    2025-02-07T18:00:41+08:002025-02-07T18:00:41+08:00

    不需要使用 Selenium,只需在 shell 中执行简单的 curl 请求即可获得结果:

    curl https://gallica.bnf.fr/services/ajax/notice/ark:/12148/cb42768809f/date
    

    我如何找到这个?只需打开浏览器的 devtools,选择网络选项卡,然后单击“详细信息”,就会出现一个新的 GET 条目。

    • 2
  2. Best Answer
    S A
    2025-02-07T20:07:00+08:002025-02-07T20:07:00+08:00

    正如@iliak提到的,您可以通过 get 请求获取信息。您必须插入services/ajax/notice/您的 URL。然后您必须解析 json 以获取数据。

    对于 selenium,请尝试以下代码。它获取信息并使用 pandas 格式化数据。

    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 selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    import time
    import pandas as pd
    
    # Configuration Selenium
    chrome_options = Options()
    chrome_options.add_argument("--headless")  # Mode sans interface graphique
    driver = webdriver.Chrome(options=chrome_options)
    wait = WebDriverWait(driver, 10)
    
    def get_metadata_from_notice(url):
        driver.get(url)
    
        details = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div#moreInfosRegion")))
        details.click()
        metadata_section = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "dl.noticeDetailsArea")))
        # metadata_text = metadata_section.text
        # return {"url": url, "metadata": metadata_text}
    
        titles = metadata_section.find_elements(By.XPATH,"./dt")
        data =[]
        for title in titles:
            content = title.find_element(By.XPATH,"./following-sibling::dd[1]").text
            data.append({"Title":title.text, "Content":content})
        return data
    
    
    # Test sur une URL
    test_url = "https://gallica.bnf.fr/ark:/12148/cb42768809f/date"
    df = pd.DataFrame(get_metadata_from_notice(test_url))
    print(df)
    
    # Fermer Selenium
    driver.quit()
    

    输出:

                     title                                            content
    0              Title :   Bulletin paroissial (Valence (Drôme), Paroiss...
    1              Title :   Bulletin paroissial mensuel de la cathédrale ...
    2          Publisher :                                        F. Rouet ()
    3   Publication date :                                               1907
    4            Subject :   Guerre mondiale (1914-1918) -- Aspect religie...
    5       Relationship :     http://catalogue.bnf.fr/ark:/12148/cb42768809f
    6           Language :                                             french
    7           Language :                                             French
    8         Identifier :                        ark:/12148/cb42768809f/date
    9             Source :   Bibliothèque nationale de France, département...
    10
    11
    
    • 1

相关问题

  • 多个复选框单击不起作用。它总是点击第一个元素

  • 如何使用 Selenium Web 驱动程序和 Python 查找 div 数据元素

  • WebDriver 和 NUnit - [测试] 最佳实践

  • selenium.common.exceptions.ElementNotInteractableException

  • Xpath如何查找包含unicode文本的元素?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    重新格式化数字,在固定位置插入分隔符

    • 6 个回答
  • Marko Smith

    为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会?

    • 2 个回答
  • Marko Smith

    VScode 自动卸载扩展的问题(Material 主题)

    • 2 个回答
  • Marko Smith

    Vue 3:创建时出错“预期标识符但发现‘导入’”[重复]

    • 1 个回答
  • Marko Smith

    具有指定基础类型但没有枚举器的“枚举类”的用途是什么?

    • 1 个回答
  • Marko Smith

    如何修复未手动导入的模块的 MODULE_NOT_FOUND 错误?

    • 6 个回答
  • Marko Smith

    `(表达式,左值) = 右值` 在 C 或 C++ 中是有效的赋值吗?为什么有些编译器会接受/拒绝它?

    • 3 个回答
  • Marko Smith

    在 C++ 中,一个不执行任何操作的空程序需要 204KB 的堆,但在 C 中则不需要

    • 1 个回答
  • Marko Smith

    PowerBI 目前与 BigQuery 不兼容:Simba 驱动程序与 Windows 更新有关

    • 2 个回答
  • Marko Smith

    AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String”

    • 1 个回答
  • Martin Hope
    Fantastic Mr Fox msvc std::vector 实现中仅不接受可复制类型 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant 使用 chrono 查找下一个工作日 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor 构造函数的成员初始化程序可以包含另一个成员的初始化吗? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský 为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul C++20 是否进行了更改,允许从已知绑定数组“type(&)[N]”转换为未知绑定数组“type(&)[]”? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann 为什么 {2,3,10} 和 {x,3,10} (x=2) 的顺序不同? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller 在 5.2 版中,bash 条件语句中的 [[ .. ]] 中的分号现在是可选的吗? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench 为什么双破折号 (--) 会导致此 MariaDB 子句评估为 true? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng 为什么 `dict(id=1, **{'id': 2})` 有时会引发 `KeyError: 'id'` 而不是 TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String” 2024-03-20 03:12:31 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve