【问题标题】:List links in web page with python使用python列出网页中的链接
【发布时间】:2018-01-17 22:56:13
【问题描述】:

我正在尝试编写一个 python 脚本来列出网页中包含某些子字符串的所有链接。我遇到的问题是该网页有多个“页面”,因此它不会弄乱整个屏幕。以https://www.go-hero.net/jam/17/solutions/1/1/C++ 为例。

这是我目前所拥有的:

import requests
from bs4 import BeautifulSoup
url = "https://www.go-hero.net/jam/17/solutions/1/1/C++"
response = requests.get(url)
soup = BeautifulSoup(response.content, "html5lib")
links = soup.find_all('a')

for tag in links:
  link = tag.get('href', None)
  if link is not None and 'GetSource' in link:
    print(link)

关于如何让它发挥作用的任何建议?提前致谢。

【问题讨论】:

    标签: python request


    【解决方案1】:

    编辑/更新: 使用Selenium,您可以在抓取 html 之前单击页面链接以将所有内容收集到 html 中。当您单击页面时,许多/大多数带有分页的网站不会收集 html 中的所有文本,但我注意到您提供的示例确实如此。看看at this SO question 的一个快速示例,让 Selenium 与 BeautifulSoup 一起工作。以下是在代码中使用它的方法:

    import requests
    from bs4 import BeautifulSoup
    from selenium import webdriver
    
    driver = webdriver.Firefox()
    original_url = "https://www.go-hero.net/jam/17/solutions/1/1/C++"
    driver.get(original_url)
    
    # click the links for pages 1-29
    for i in range(1, 30):
        path_string = '/jam/17/solutions/1/1/C++#page-' + str(i)
        driver.find_element_by_xpath('//a[@href=' + path_string + ']').click()
    
    # scrape from the accumulated html
    html = driver.page_source
    soup = BeautifulSoup(html)
    links = soup.find_all('a')
    
    # proceed as normal from here
    for tag in links:
        link = tag.get('href', None)
        if link is not None and 'GetSource' in link:
            print(link)
    

    原始答案:对于您上面提供的link,您可以简单地遍历可能的网址并在循环中运行您的抓取代码:

    import requests
    from bs4 import BeautifulSoup
    original_url = "https://www.go-hero.net/jam/17/solutions/1/1/C++"
    
    # scrape from the original page (has no page number)
    response = requests.get(original_url)
    soup = BeautifulSoup(response.content, "html5lib")
    links = soup.find_all('a')
    
    # prepare to scrape from the pages numbered 1-29
    # (note that the original page is not numbered, and the next page is "#page-1")
    url_suffix = '#page-'
    
    for i in range(1, 30):
        # add page number to the url
        paginated_url = original_url + url_suffix + str(i)
        response = requests.get(paginated_url)
        soup = BeautifulSoup(response.content, "html5lib")
        # append resulting list to 'links' list
        links += soup.find_all('a')
    
    # proceed as normal from here
    for tag in links:
        link = tag.get('href', None)
        if link is not None and 'GetSource' in link:
            print(link)
    

    我不知道您是否介意结果中会出现重复。您将在 link 列表中得到重复的结果,就像代码当前一样,但您可以将链接添加到 Set 或其他东西以轻松解决此问题。

    【讨论】:

    • 这种方法的问题在于它实际上并没有获得第 2、3、4 页等的链接。相反,我们一遍又一遍地从第 0 页获得相同的链接。这可以通过从另一个页面查找一些用户名来验证。
    • 我添加了一个更好的方法,并将原始方法留在了答案的底部。我添加的方法使用硒来做你想做的事。我相信原始方法在加载页面 2、3、4 等方面确实有效,但你是对的,它也加载页面 0 总共 30 次。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-12
    • 1970-01-01
    • 1970-01-01
    • 2021-12-21
    • 2012-07-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多