【问题标题】:Better way of capturing multiple same tags?捕获多个相同标签的更好方法?
【发布时间】:2021-06-07 11:18:05
【问题描述】:

我正在尝试创建一个抓取下载链接的刮板,我想使用正则表达式,但这对我来说将是一场噩梦,我找到了这个名为 BeautifulSoup 的库,我正在尝试捕获div class="article-content" 的子项中的 url,即<p> 标签,这个<h3> 是 url 的名称,我不想将所有 url 合并到一个列表中,而是使用字典,这是关键name(<h3>) 和 value 是 url 列表,这里的代码就够了。

import requests
from bs4 import BeautifulSoup

def scrape():
    resp = requests.get('https://www.animeout.xyz/love-live-nijigasaki-gakuen-school-idol-doukoukai-1080p-300mb720p-150mbepisode-1/')
    soup = BeautifulSoup(resp.text,'html.parser')
    contents = soup.find('div',class_='article-content')
    output = {}
    for tag in contents.children:
        if tag.name == 'h3':
            name = tag.text
            links = []
            for sibling in tag.next_siblings:
                if sibling.name == 'p':
                    for link in sibling.find_all('a',text='Direct Download'):
                        links.append(link.get('href'))
                if sibling.name == 'h3':
                    output.update({name:links})
                    break

到目前为止,我只设法捕获了 1 个密钥,有没有 Pythonic 方法可以做到这一点?

【问题讨论】:

  • 请将标题更改为对未来面临类似问题的用户有用的内容
  • 没问题,我已经编辑了标题。

标签: python html for-loop beautifulsoup python-requests


【解决方案1】:

你可能想试试这个:

import json
import re

import requests
from bs4 import BeautifulSoup


def scrape(source_url):
    soup = BeautifulSoup(
        requests.get(source_url).text,
        'html.parser',
    )
    headers = [
        h.getText() for h in soup.find_all("h3") if "Direct" in h.getText()
    ]
    links = [
        anchor["href"] for anchor
        in soup.find_all(lambda t: t.name == "a" and "Direct" in t.text)
    ]
    return {
        header: [
            link for link in links
            if re.search(r"\d{3,4}p", header).group(0) in link
        ] for header in headers
    }


data = scrape("https://www.animeout.xyz/love-live-nijigasaki-gakuen-school-idol-doukoukai-1080p-300mb720p-150mbepisode-1/")

print(json.dumps(data, indent=2))


您只有一个键的原因是键 必须 是唯一的,但链接的名称不是。用一些独特的东西来改变它,例如索引号或带有分辨率的系列标题。

样本输出:

{
  "Love Live! Nijigasaki Gakuen School Idol Doukoukai (main) Direct Download Links (300MB \u2013 1080p)(Encoded)": [
    "http://nimbus.animeout.com/series/00RAPIDBOT/Love Live Nijigasaki Gakuen School Idol Doukoukai/[AnimeOut] Love Live Nijigasaki Gakuen School Idol Doukoukai - 01 [1080pp][1080pp][Erai-raws][RapidBot].mkv",
    "http://nimbus.animeout.com/series/00RAPIDBOT/Love Live Nijigasaki Gakuen School Idol Doukoukai/[AnimeOut] Love Live Nijigasaki Gakuen School Idol Doukoukai - 01 [v2][1080pp][1080pp][Erai-raws][RapidBot].mkv",
    "http://nimbus.animeout.com/series/00RAPIDBOT/Love Live Nijigasaki Gakuen School Idol Doukoukai/[AnimeOut] Love Live Nijigasaki Gakuen School Idol Doukoukai - 01 [1080pp][1080pp][Erai-raws][RapidBot].mkv",

and so on ...

【讨论】:

  • 感谢您为回答我的问题 +1 所做的努力,我确实考虑过这种方法,但实际上并不限于此,我真正想要做的是将这些 url 存储在值中. {'baduker':['https://stackoverflow.com/users/6106791/baduker','https://https://codereview.stackexchange.com/users/163501/baduker']} 以一种简洁的方式。
  • @Hans 我已经更新了答案。另外,如果您发现它无论如何有用,请考虑接受它。见 - stackoverflow.com/help/someone-answers
  • 我确实考虑过,但我犹豫了,因为“直接”可能不存在,因此跳过它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多