Продолжайте получать 'TypeError: объект' NoneType 'не вызывается' с красивым супом и python3 - PullRequest
0 голосов
/ 27 августа 2018

Я новичок и борюсь за курс, поэтому эта проблема, вероятно, очень проста, но я использую этот (по общему признанию) грязный код (сохраненный в файле x.py), чтобы извлечь ссылку и имя из веб-сайта с линейные форматы, такие как:

<li style="margin-top: 21px;">
  <a href="http://py4e-data.dr-chuck.net/known_by_Prabhjoit.html">Prabhjoit</a>
</li>

Итак, я настроил это: импорт urllib.request, urllib.parse, urllib.error из bs4 импортировать BeautifulSoup импортировать ssl # Игнорировать ошибки SSL-сертификата ctx = ssl.create_default_context () ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE

url = input('Enter - ')
html = urllib.request.urlopen(url, context=ctx).read()
soup = BeautifulSoup(html, 'html.parser')
for line in soup:
    if not line.startswith('<li'):
        continue
    stuff = line.split('"')
    link = stuff[3]
    thing = stuff[4].split('<')
    name = thing[0].split('>')
    count = count + 1
    if count == 18:
        break
print(name[1])
print(link)

И он продолжает выдавать ошибку:

Traceback (most recent call last):
  File "x.py", line 15, in <module>
    if not line.startswith('<li'):
TypeError: 'NoneType' object is not callable

Я боролся с этим часами, и буду благодарен за любые предложения.

1 Ответ

0 голосов
/ 27 августа 2018

line не является строкой и не имеет метода startswith(). Это BeautifulSoup Tag объект , потому что BeautifulSoup проанализировал исходный текст HTML в расширенную объектную модель. Не пытайтесь воспринимать это как текст!

Ошибка вызвана тем, что если вы обращаетесь к какому-либо атрибуту объекта Tag, о котором он не знает, он выполняет поиск дочернего элемента с таким именем (поэтому здесь он выполняет line.find('startswith')), и, поскольку нет элемента с таким именем, возвращается None. None.startswith() затем завершается с ошибкой, которую вы видите.

Если вы хотите найти 18-й <li> элемент, просто спросите BeautifulSoup для этого конкретного элемента:

soup = BeautifulSoup(html, 'html.parser')
li_link_elements = soup.select('li a[href]', limit=18)
if len(li_link_elements) == 18:
    last = li_link_elements[-1]
    print(last.get_text())
    print(last['href'])

При этом используется селектор CSS , чтобы найти только элементы ссылки <a>, родительские элементы которых являются элементами <li> и которые имеют атрибут href. Поиск ограничен только 18 такими тегами, и последний печатается, но только если мы действительно нашли 18 на странице.

Текст элемента извлекается с помощью метода Element.get_text() , который будет включать текст из любых вложенных элементов (например, <span> или <strong> или другой дополнительной разметки), а также href Атрибут доступен с использованием стандартной индексации .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...