【问题标题】:Extract count of specific links from a web page.从网页中提取特定链接的数量。
【发布时间】:2018-08-14 01:32:08
【问题描述】:

我正在使用 BeautifulSoup 编写一个 python 脚本。我需要抓取一个网站并计算唯一链接,忽略以“#”开头的链接。

网页上是否存在以下链接的示例:

https://www.stackoverflow.com/questions

https://www.stackoverflow.com/foo

https://www.cnn.com/

对于这个例子,唯一的两个链接将是(去除主域名后的链接信息):

https://stackoverflow.com/    Count 2
https://cnn.com/              Count 1

注意:这是我第一次使用 python 和网络抓取工具。

我提前感谢所有帮助。

这是我迄今为止尝试过的:

from bs4 import BeautifulSoup
import requests


url = 'https://en.wikipedia.org/wiki/Beautiful_Soup_(HTML_parser)'

r = requests.get(url)

soup = BeautifulSoup(r.text, "html.parser")


count = 0

for link in soup.find_all('a'):
    print(link.get('href'))
    count += 1

【问题讨论】:

    标签: python web-scraping beautifulsoup


    【解决方案1】:

    有一个名为urlparse 的函数从urllib.parse 可以得到netloc 的url。还有一个新的很棒的 HTTP 库,名为 requests_html,它可以帮助您获取源文件中的所有链接。

    from requests_html import HTMLSession
    from collections import Counter
    from urllib.parse import urlparse
    
    session = HTMLSession()
    r = session.get("the link you want to crawl")
    unique_netlocs = Counter(urlparse(link).netloc for link in r.html.absolute_links)
    for link in unique_netlocs:
        print(link, unique_netlocs[link])
    

    【讨论】:

    • 这行得通,但我只需要显示域和该域的计数。例如,如果网页上的链接是 www.foo.com/bar、www.foo.com/bash、www.foo.com/bar。输出将是 www.foo.com 3
    【解决方案2】:

    你也可以这样做:

    from bs4 import BeautifulSoup
    from collections import Counter
    import requests
    
    soup = BeautifulSoup(requests.get("https://en.wikipedia.org/wiki/Beautiful_Soup_(HTML_parser)").text, "html.parser")
    
    foundUrls = Counter([link["href"] for link in soup.find_all("a", href=lambda href: href and not href.startswith("#"))])
    foundUrls = foundUrls.most_common()
    
    for item in foundUrls:
        print ("%s: %d" % (item[0], item[1]))
    

    soup.find_all 行检查是否每个 atag 都设置了 href 以及它是否不以 # 字符开头。 Counter 方法按值对每个列表条目和most_common 订单的出现次数进行计数。

    for 循环只打印结果。

    【讨论】:

    • 这行得通,但我只需要显示域和该域的计数。例如,如果网页上的链接是 www.foo.com/bar、www.foo.com/bash、www.foo.com/bar。输出将是 www.foo.com 3
    【解决方案3】:

    我这样做的方法是使用漂亮的汤找到所有链接,然后确定哪个链接重定向到哪个位置:

    def get_count_url(url): # get the umber of links having the same domain and suffix
    r = requests.get(url)
    soup = BeautifulSoup(r.text, "html.parser")
    count = 0
    urls={} #dictionary for the domains
    # input_domain=url.split('//')[1].split('/')[0]
    #library to extract the exact domain( ex.- blog.bbc.com and bbc.com have the same domains )
    input_domain=tldextract.extract(url).domain+"."+tldextract.extract(url).suffix 
    for link in soup.find_all('a'):
        word =link.get('href')
        # print(word)
        if word:
            # Same website or domain calls
            if "#" in word or word[0]=="/": #div call or same domain call
                if not input_domain in urls:
                    # print(input_domain)
                    urls[input_domain]=1 #if first encounter with the domain
                else:
                    urls[input_domain]+=1 #multiple encounters
            elif "javascript" in word:
                # javascript function calls (for domains that use modern JS frameworks to display information)
                if not "JavascriptRenderingFunctionCall" in urls:
                    urls["JavascriptRenderingFunctionCall"]=1
                else:
                    urls["JavascriptRenderingFunctionCall"]+=1
            else:
                # main_domain=word.split('//')[1].split('/')[0]
                main_domain=tldextract.extract(word).domain+"." +tldextract.extract(word).suffix
                # print(main_domain)
                if main_domain.split('.')[0]=='www':
                    main_domain = main_domain.replace("www.","") # removing the www
                if not main_domain in urls: # maintaining the dictionary
                    urls[main_domain]=1
                else:
                    urls[main_domain]+=1
            count += 1
    
    for key, value in urls.items(): # printing the dictionary in a paragraph format for better readability
        print(key,value)
    return count    
    

    tld extract 找到正确的 url 名称,soup.find_all('a') 找到一个标签。 if 语句检查同域重定向、javascript 重定向或其他域重定向。

    【讨论】:

      猜你喜欢
      • 2011-07-04
      • 2017-04-18
      • 2015-03-15
      • 1970-01-01
      • 1970-01-01
      • 2014-01-30
      • 2020-03-22
      • 1970-01-01
      • 2021-11-20
      相关资源
      最近更新 更多