У меня есть копии этого самого кода, который я пытаюсь сделать, и каждый раз, когда я его копирую, он работает неправильно. Я более чем разочарован и не могу понять, где он не работает. То, что я пытаюсь сделать, это перейти на веб-сайт, отбросить разные страницы рейтингов, которые обозначены A, B, C... и т.д. Затем я перехожу на каждый сайт, чтобы вытащить общее количество страниц, которые они используют. Я пытаюсь очистить <span class='letter-pages' href='/ratings/A/1'
и т.д. Что я делаю неправильно?
import requests
from bs4 import BeautifulSoup
url = "https://www.brightscope.com/ratings/"
page = requests.get(url)
soup = BeautifulSoup(page.text, 'html.parser')
hrefs = []
ratings = []
ks = []
pages_scrape = []
for href in soup.findAll('a'):
if 'href' in href.attrs:
hrefs.append(href.attrs['href'])
for good_ratings in hrefs:
if good_ratings.startswith('/ratings/'):
ratings.append(url[:-9]+good_ratings)
# elif good_ratings.startswith('/401k'):
# ks.append(url[:-9]+good_ratings)
del ratings[0]
del ratings[27:]
print(ratings)
for each_rating in ratings:
page = requests.get(each_rating)
soup = BeautifulSoup(page.text, 'html.parser')
for href in soup.find('span', class_='letter-pages'):
#Not working Here
pages_scrape.append(href.attrs['href'])
# Will print all the anchor tags with hrefs if I remove the above comment.
print(href)
Вы пытаетесь получить href преждевременно. Вы пытаетесь извлечь атрибут непосредственно из span
тега, который вложен тегами, а не список a
a
тег.
for each_rating in ratings:
page = requests.get(each_rating)
soup = BeautifulSoup(page.text, 'html.parser')
span = soup.find('span', class_='letter-pages')
for a in span.find_all('a'):
href = a.get('href')
pages_scrape.append(href)
Я не тестировал это на всех страницах, но он работал для первого. Вы указали, что на некоторых страницах контент не соскабливается, что связано с поиском span
возвращающим None
. Чтобы обойти это, вы можете сделать что-то вроде:
for each_rating in ratings:
page = requests.get(each_rating)
soup = BeautifulSoup(page.text, 'html.parser')
span = soup.find('span', class_='letter-pages')
if span:
for a in span.find_all('a'):
href = a.get('href')
pages_scrape.append(href)
print(href)
else:
print('span.letter-pages not found on ' + page)
В зависимости от вашего варианта использования вы можете захотеть сделать что-то другое, но это покажет вам, какие страницы не соответствуют вашей модели скребков, и их необходимо вручную исследовать.
span
с помощью if / else. Я обновлю свой пост, чтобы продемонстрировать.
Вы, вероятно, find_all
find
find_all
вместо find
- так что измените
for href in soup.find('span', class_='letter-pages'):
в
for href in soup.find_all('span', class_='letter-pages'):
Вы хотите выполнять итерацию по списку тегов, а не по одному тегу. find
даст вам один объект тега. Когда вы перебираете один тег, вы итерации получаете объекты NavigableString
. find_all
предоставляет вам список объектов тегов, которые вы хотите.
AttributeError: 'NavigableString' object has no attribute 'attrs'