Парсинг не работает на второй странице
На сайте данные приведены в виде карточек (при наведении на них - увеличиваются [data-animation="zooming"]). Парсинг с помощью requests и BeautifulSoup работает на первой странице, на второй для ссылок a href Python выбивает ошибку: AttributeError: 'NoneType' object has no attribute 'attrs' и сохраняет csv с результатами только первой страницы, но второй и следующих нет. Использование fake_useragent и session = HTMLSession() не решает проблему. Где на view-source находятся данные для payload = { "jsonQuery":{ }}? Или какой наилучший способ все же собрать данные в таблицу - Node.js и Puppeteer?
Сайт - https://armacad.info/summer-schools?page=5&order=latest
Код:
import csv
import re
import time
from fake_useragent import UserAgent
from bs4 import BeautifulSoup
from random import randint
from time import sleep
from requests_html import HTMLSession
session = HTMLSession()
ua = UserAgent()
category = 'summer-schools'
last_page = 4
filename = f'armacad4-{category}-all.csv'
outfile = open(filename,'w', encoding='utf-8', newline='')
writer = csv.writer(outfile)
writer.writerow(['title', 'link'])
sleep(randint(5,10))
pages = list(range(1,int(last_page)+1))
for page in pages:
URL = f'https://armacad.info/{category}?page={page}&order=latest'
html = session.get(URL, headers={'User-Agent':ua.random})
soup = BeautifulSoup(html.content, 'html.parser')
jobs_list = soup.find_all('div', {'class': re.compile(r'col-md-4')})
sleep(randint(5,10))
print ('Обрабатывается страница: %s' %(page))
for card in jobs_list:
title = card.find('span', class_='h4').text if card.find('span', class_='h4') is not None else ''
link = card.find('a').attrs['href'] if card.find('a').attrs['href'] is not None else ''
writer.writerow([title, link])
outfile.close()
print ('Сбор завершен')
Ответы (1 шт):
Немного отрефакторил. У меня заработало.
import csv
from fake_useragent import UserAgent
from bs4 import BeautifulSoup
from random import randint
from time import sleep
from requests_html import HTMLSession
session = HTMLSession()
ua = UserAgent()
category = 'summer-schools'
last_page = 4
filename = f'armacad4-{category}-all.csv'
outfile = open(filename, 'w', encoding='utf-8', newline='')
writer = csv.writer(outfile)
writer.writerow(['title', 'link'])
pages = list(range(1, int(last_page) + 1))
for page in pages:
URL = f'https://armacad.info/{category}?page={page}&order=latest'
html = session.get(URL, headers={'User-Agent': ua.random})
soup = BeautifulSoup(html.content, 'html.parser')
jobs_list = soup.find_all('div', {'class': 'col-md-4'})
sleep_n = randint(2, 6)
print(f"sleep for {sleep_n}")
sleep(sleep_n)
print('Обрабатывается страница: %s' % page)
for card in jobs_list:
print("parsing card")
title = ''
link = ''
if card.find('span', class_='h4') is not None:
title = card.find('span', class_='h4').text
print(f"{title=}")
if card.find('a') is not None:
link = card.find('a').attrs['href']
print(f"{link=}")
writer.writerow([title, link])
print("data written\n", "*"*20)
outfile.close()
print('Сбор завершен')
проблема была вот здесь
link = card.find('a').attrs['href'] if card.find('a').attrs['href'] is not None else ''
if card.find('a').attrs['href'] is not None -> if card.find('a') is not None
P.S. Писать длинные выражения в одну строку плохо для чтения.
Код пишется один раз, читается 10.
Так же есть максимальный размер строки который удобно читать.
Обычно это 80, 100, 120. Обычно комманда договаривается об этом.