在Beautiful Soup 4中无法调用“ NoneType”对象

时间:2019-03-16 02:34:05

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

我对python还是很陌生,并开始尝试使用Beautiful Soup4。我尝试编写代码,将所有链接都放在一个页面上,然后重复这些链接,直到对整个网站进行了解析。

import bs4 as bs
import urllib.request as url

links_unclean = []
links_clean = []
soup = bs.BeautifulSoup(url.urlopen('https://pythonprogramming.net/parsememcparseface/').read(), 'html.parser')

for url in soup.find_all('a'):
    print(url.get('href'))
    links_unclean.append(url.get('href'))

for link in links_unclean:
    if (link[:8] == 'https://'):
        links_clean.append(link)

print(links_clean)

while True:
    for link in links_clean:
        soup = bs.BeautifulSoup(url.urlopen(link).read(), 'html.parser')

        for url in soup.find_all('a'):
            print(url.get('href'))
            links_unclean.append(url.get('href'))

        for link in links_unclean:
            if (link[:8] == 'https://'):
                links_clean.append(link)

        links_clean = list(dict.fromkeys(links_clean))



input()

但是我现在遇到此错误:

  

'NoneType'对象不可调用        第20行,在        汤= bs.BeautifulSoup(url.urlopen(link).read(),        'html.parser')

您能帮忙吗?

2 个答案:

答案 0 :(得分:0)

在导入模块as时要小心。在这种情况下,第2行上的url会在您进行迭代的for循环中被覆盖。

这是一个简短的解决方案,它还会只返回包含 https 的URL作为 href 属性的一部分:

from bs4 import BeautifulSoup
from urllib.request import urlopen


content = urlopen('https://pythonprogramming.net/parsememcparseface/')
soup = BeautifulSoup(content, "html.parser")
base = soup.find('body')

for link in BeautifulSoup(str(base), "html.parser").findAll("a"):
    if 'href' in link.attrs:
        if 'https' in link['href']:
            print(link['href'])

但是,由于页面上带有HTML标记的错误导致并非所有链接都被捕获,因此这会绘制不完整的图片。我是否也可以推荐以下替代方法,它非常简单并且可以在您的情况下完美运行(注释:您将需要软件包Requests-HTML

from requests_html import HTML, HTMLSession

session = HTMLSession()
r = session.get('https://pythonprogramming.net/parsememcparseface/')

for link in r.html.absolute_links:
    print(link)

这将输出所有URL,包括引用相同域中其他URL的URL和作为外部网站的URL。

答案 1 :(得分:0)

我会考虑使用attribute = value css选择器,并使用^运算符来指定href属性以https开头。这样您将只有有效的协议。另外,请使用集合理解来确保没有重复,并使用Session重用连接。

from bs4 import BeautifulSoup as bs
import requests
import pandas as pd
final = []

with requests.Session() as s:
    r = s.get('https://pythonprogramming.net/parsememcparseface/')
    soup = bs(r.content, 'lxml')
    httpsLinks = {item['href'] for item in soup.select('[href^=https]')}
    for link in httpsLinks:
        r = s.get(link)
        soup = bs(r.content, 'lxml')
        newHttpsLinks = [item['href'] for item in soup.select('[href^=https]')]
        final.append(newHttpsLinks)
tidyList =  list({item for sublist in final for item in sublist})  
df = pd.DataFrame(tidyList)
print(df)