【问题标题】:scrape a list of links in beautiful soup using range使用范围刮取美丽汤中的链接列表
【发布时间】:2020-10-31 22:15:39
【问题描述】:

我一直在练习我的网页抓取技巧,遇到了一个问题,我通过抓取带有 id="secret-word" 的段落标签来过滤一组 10 个链接。我想出了如何为第一个链接执行此操作,所以我认为循环处理并一次获取它们会很好。

这是我从中获取链接的网站(链接位于底部):https://keithgalli.github.io/web-scraping/webpage.html

这是我想出的代码..但我无法弄清楚如何在不将其与 while 循环分开的情况下获取元素 0 (n=0)。也许你不能?

我拉出了所有链接的列表:

new_listc = links_with_text1[19:]

['challenge/file_1.html',
 'challenge/file_2.html',
 'challenge/file_3.html',
 'challenge/file_4.html',
 'challenge/file_5.html',
 'challenge/file_6.html',
 'challenge/file_7.html',
 'challenge/file_8.html',
 'challenge/file_9.html',
 'challenge/file_10.html']

我使用请求连接到每个站点:

t = [requests.get(f"https://keithgalli.github.io/web-scraping/{url}", timeout=5) for url in new_listc]

我通过漂亮的汤循环了所有链接,并从每个链接中抓取了秘密单词以获取单词列表。我想知道是否有更简洁的方法可以做到这一点,以及为什么我必须将第一个挑战文件放在循环之外?!

 n=0
    tsoup = bs(t[n].content)  
        
    test_soup = tsoup.select("p#secret-word")
    #print(n)
    x = [t.text for t in test_soup]
    print(x)
    while n in range(0,9):
        n += 1
        #print(n)
        tsoup = bs(t[n].content)  
        test_soup = tsoup.select("p#secret-word")
        x = [t.text for t in test_soup]
        print(x)
        #print(tsoup.prettify())
        if n > 9:
            break

['Make']
['sure']
['to']
['smash']
['that']
['like']
['button']
['and']
['subscribe']
['!!!']

【问题讨论】:

  • 这解决了它!:code for n in range(len(oo)): count = count + oo[n] tsoup = bs(t[n].content) test_soup = tsoup.select("p#secret-word") for y in test_soup: print(y.text) code

标签: python-3.x web-scraping beautifulsoup


【解决方案1】:

老实说,您的方法确实没有任何问题,而且您通过“更清洁的方式”询问人们的偏好,恕我直言。所以,这是我的。

import requests
from bs4 import BeautifulSoup


def get_content(number: int) -> str:
    url = f"https://keithgalli.github.io/web-scraping/challenge/file_{number}.html"
    soup = BeautifulSoup(
        requests.get(url).text, "html.parser"
    ).select_one("p#secret-word")
    return soup.getText(strip=True)


print(" ".join(get_content(number) for number in range(1, 11)))

输出:

Make sure to smash that like button and subscribe !!!

上面的答案假设有 10 页面要循环,但如果你需要先刮掉主要的,我会试试这个:

import requests
from bs4 import BeautifulSoup

the_url = "https://keithgalli.github.io/web-scraping/webpage.html"


def make_soup_first(url: str) -> BeautifulSoup:
    return BeautifulSoup(requests.get(url).text, "html.parser")


def get_follow_links(main_link: str) -> list:
    soup = make_soup_first(main_link)
    return [
        a["href"] for a in soup.find_all(
            lambda t: t.name == "a" and "File" in t.text
        )
    ]


def get_content(follow_link: str) -> str:
    url = f"https://keithgalli.github.io/web-scraping/{follow_link}"
    return make_soup_first(url).select_one("p#secret-word").getText(strip=True)


print(" ".join(get_content(link) for link in get_follow_links(the_url)))

它给出与上面相同的输出:

Make sure to smash that like button and subscribe !!!

【讨论】:

  • 感谢您的反馈!我也喜欢你把它分解成函数的方式,因为它使它更容易跟踪和保持清洁!!!我将致力于组织我的代码。 :)
【解决方案2】:

您必须将第一个质询文件放在循环之外的原因是因为循环的第一行将 n 递增 1,因此在第一次迭代时它访问 t[1] 而不是 t[0]。您可以通过将该行移至循环末尾来解决此问题,但更简洁的方法是使用 for 循环:

tsoup = bs(t[n].content)  
test_soup = tsoup.select("p#secret-word")
for secret_word in test_soup:
    print(secret_word.text)

【讨论】:

    猜你喜欢
    • 2021-01-15
    • 2014-05-28
    • 2020-12-13
    • 2019-03-13
    • 2020-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多