【问题标题】:Python scraping of Wikipedia category page维基百科分类页面的 Python 抓取
【发布时间】:2022-01-10 23:19:53
【问题描述】:

我有这个维基百科分类页面:https://fr.wikipedia.org/wiki/Cat%C3%A9gorie:Pi%C3%A8ce_de_th%C3%A9%C3%A2tre_du_XVIIIe_si%C3%A8cle

我想打开列出的每个剧本的页面(例如https://fr.wikipedia.org/wiki/L%27Oiseau_vert)并打印它的第一句话(例如L'Oiseau vert (L'augellino belverde) est une comédie de Carlo Gozzi ( auteur italien de pièces de téâtre)parue en 1765)。第 1 列的播放标题和第 2 列的第一个句子的数据框也很好。

我尝试通过BeautifulSoup 获取所有页面链接并使用wikipedia.summary() 打印第一句话,但结果并不理想,因为wikipedia 模块经常重定向到错误的文章。部分问题可能是由剧名中的法语特殊字符(é、â等)引起的

有没有更好的方法可以直接从分类页面访问单个文章?

This question 似乎相关但没有进一步帮助我。

【问题讨论】:

    标签: python web-scraping wikipedia


    【解决方案1】:

    有一种更好的方法可以直接从分类页面访问单个文章:Wikipedia API!

    你可以试试这个:

    import requests
    
    url = "https://fr.wikipedia.org/w/api.php"
    params = {
        "action": "query",
        "cmtitle": "Catégorie:Pièce de théâtre du XVIIIe siècle",
        "cmlimit": "50",
        "list": "categorymembers",
        "format": "json"
    }
    req = requests.get(url=url, params=params)
    pages = req.json()['query']['categorymembers']
    
    # here just iterate over category individual pages
    for page in pages:
        # eg. page = {'pageid': 622757, 'ns': 0, 'title': 'Les Acteurs de bonne foi'}
        _url = 'https://fr.wikipedia.org/w/api.php'
        _params = {
            'format': 'json',
            'action': 'query',
            'prop': 'extracts',
            'exintro': True,
            'explaintext': True,
            'redirects': 1,
            'pageids': page['pageid'],
        }
        req = requests.get(_url, _params)
        summary = req.json()['query']['pages'][str(page['pageid'])]['extract']
    

    在“Les Acteurs de bonne foi”的情况下,摘要返回:

    'Les Acteurs de bonne foi est une comédie en un acte et en prose de Marivaux, jouée pour la première fois chez Quinault cadette le 30 1748 年 10 月。\nMarivaux fit jouer les Acteurs de bonne foi au Théâtre-Français en 1755, mais la pièce ne réussit pas。 Elle fut publiée pour la première fois dans le Conservateur de 1757 年 11 月。 L'intérêt de la pièce repose principalement sur un jeu qu'entretient Marivaux avec son lecteur grâce à la mise en abyme。效果,文本 mele au sein d'une meme page : entretien des acteurs sur leurs vies 各自,对话 sur les possibilités de jeu et de mise en scène ainsi que répliques d'un texte qui est alors joué。 Dans cette piece, qui est la dernière que l'auteur ait fait jouer sur un grand téâtre, où la scène de comédie est rapidement détournée et donne lieu à une 混乱 entre la situation réelle et la scène jouée, la mise en abyme révèle l'importance de l'illusion théâtrale。'

    【讨论】:

    • 为什么不在第二个get请求中使用params
    • 你是对的。为了保持一致性,我对其进行了编辑。
    • 另外,您不必使用会话,也不需要导入 bs4 :)
    【解决方案2】:

    这是一个示例,您可以如何仅使用beautifulsoup 实现这一目标:

    import requests
    from bs4 import BeautifulSoup
    
    
    def get_categories(data):
        print("Getting categories...")
        categories = {}
        soup = BeautifulSoup(data, "lxml")
        group_divs = soup.find_all("div", {"class": "mw-category-group"})
        for div in group_divs:
            links = div.find_all("a")
            for link in links:
                title = link.get("title")
                href = link.get("href")
                categories[title] = "https://fr.wikipedia.org" + href
        print(f"Found Categories: {len(categories)}")
        return categories
    
    
    def get_first_paragraph(data):
        soup = BeautifulSoup(data, "lxml")
        parser_output = soup.find("div", {"class": "mw-parser-output"})
        first_paragraph = parser_output.find("p", {"class": None}, recursive=False)
        return first_paragraph.text
    
    
    def process_categories(categories):
        result = {}
        for title, link in categories.items():
            print(f"Processing Piece: {title}, on link: {link}")
            data = requests.get(link).content
            first_paragraph = get_first_paragraph(data)
            result[title] = first_paragraph.strip()
        return result
    
    
    def clean_categories(categories):
        return {k: v for k, v in categories.items() if "Catégorie" not in k}
    
    
    def main():
        categories_url = "https://fr.wikipedia.org/wiki/Cat%C3%A9gorie:Pi%C3%A8ce_de_th%C3%A9%C3%A2tre_du_XVIIIe_si%C3%A8cle"
        data_categories = requests.get(categories_url).content
        categories = get_categories(data_categories)
        categories = clean_categories(categories)
        result = process_categories(categories)
        print(result) # create dataframe etc...
    
    
    if __name__ == "__main__":
        main()
    

    代码不言自明:

    • 首先我们找到具有category-group类的divs,提取所有a元素并得到titlehref
    • 然后对于每个 category 即片段,我们解析 HTML 并在 div 中使用 mw-parser-output 类获取第一个 p(这应该是第一句)。

    注意:我添加了clean_categories,因为category-group 捡到了不需要的东西,其中包含Catégorie

    前几部分的输出示例:

    Getting categories...
    Found Categories: 198
    Processing Piece: Les Acteurs de bonne foi, on link: https://fr.wikipedia.org/wiki/Les_Acteurs_de_bonne_foi
    Processing Piece: Adamire ou la Statue de l'honneur, on link: https://fr.wikipedia.org/wiki/Adamire_ou_la_Statue_de_l%27honneur
    Processing Piece: Agamemnon (Lemercier), on link: https://fr.wikipedia.org/wiki/Agamemnon_(Lemercier)
    Processing Piece: Agathocle (Voltaire), on link: https://fr.wikipedia.org/wiki/Agathocle_(Voltaire)
    

    结果:

    {"Adamire ou la Statue de l'honneur": "Adamire ou la Statue de l'honneur est "
                                          'la traduction par Thomas-Simon '
                                          'Gueullette de la pièce de théâtre '
                                          "italienne l'Adamira overo la Statua "
                                          "dell'Honore de Giacinto Andrea "
                                          'Cicognini représentée pour la première '
                                          'fois en France le 12 décembre 1717 à '
                                          "Paris, à l'Hôtel de Bourgogne.",
     'Agamemnon (Lemercier)': 'Agamemnon est une tragédie en cinq actes considérée '
                              "comme le chef-d'œuvre dramatique de Népomucène "
                              'Lemercier. Elle fut représentée au Théâtre de la '
                              'République le 5 floréal an V (24 avril 1797) et '
                              'valut à son auteur une célébrité immédiate.',
     'Agathocle (Voltaire)': 'Agathocle est une tragédie écrite par Voltaire, '
                             'représentée pour la première fois le 31 mai 1779, '
                             'sur la scène de la Comédie-Française.',
     'Les Acteurs de bonne foi': 'Les Acteurs de bonne foi est une comédie en un '
                                 'acte et en prose de Marivaux, jouée pour la '
                                 'première fois chez Quinault cadette le 30 '
                                 'octobre 1748.'}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-24
      • 1970-01-01
      • 1970-01-01
      • 2017-04-30
      • 1970-01-01
      • 2017-07-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多