как правильно сделать код парсера для python
я написал небольшой парсер, но не могу понять как сделать парсер названия фильмов. Вот сам код:
from bs4 import BeautifulSoup as bs
import requests
href_film = {}
count = 0
page = int( input('сколько страниц нужно спарсить: '))
page += 1
page_list = 0
while page_list < page:
url = 'https://lordserial.live/anime-serialy/' + 'page/' + str(page_list) + '/'
req = requests.get(url, headers=header)
soup = bs(req.text, 'lxml')
kart_film = soup.find_all('div', class_='th-item')
film_text = soup.find_all('div', class_='th-title')
for items in kart_film:
film_text = i.text
film_href = f'''{items.a['href']}'''
href_film[count] = film_text,film_href
count += 1
page_list += 1
with open('herf_film.json', 'w', encoding='utf-8') as file:
json.dump(href_film, file, indent=4, ensure_ascii=False)
Ответы (3 шт):
Автор решения: Сергей Ш
→ Ссылка
import requests
from bs4 import BeautifulSoup as bs
href_film = []
url_p = 'https://lordserial.live/anime-serialy/'
while True:
req = requests.get(url_p)
soup = bs(req.text, 'lxml')
for q in soup.findAll('div', class_='th-item'):
title = q.find('div', class_='th-title').text
year = q.find('div', class_='th-year').text
url = q.a['href']
href_film.append({'title': title, 'year': year, 'url': url})
try:
url_p = soup.find('div', id='pagi-load').a['href']
except Exception:
break
print(href_film)
[{'title': 'Семья шпиона', 'year': '(2022)', 'url': 'https://lordserial.live/anime-serialy/6114-semya-shpiona.html'}, {'title': 'Клинок, рассекающий демонов', 'year': '(2019)', 'url': 'https://lordserial.live/anime-serialy/1483-klinok-rassekayuwij-demonov.html'}, .... {'title': 'Боруто: Новое поколение Наруто', 'year': '(2017)', 'url': 'https://lordserial.live/anime-serialy/1466-boruto--novoe-pokolenie-naruto-1-seasone.html'}]
Автор решения: gil9red
→ Ссылка
Переписал парсер из вопроса, сохранив логику:
- Использование сессии (умеет хранить куки, общие заголовки)
- Использование парсера
html.parser- он есть из коробки, в отличии отlxml - Использование css-селекторов, это методы
selectиselect_one. У css-селекторов очень лаконичный синтаксис - Немного подправил способ составления ссылки, чтобы выглядело естественнее
- Добавлена проверка на плохие статусы HTTP через
raise_for_status - Формат записей в виде списка, я думаю удобнее, чем словарем
Пример:
import requests
from bs4 import BeautifulSoup as bs
BASE_URL = 'https://lordserial.live/anime-serialy/'
session = requests.Session()
session.headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:100.0) Gecko/20100101 Firefox/100.0'
items = []
max_page = 5
for page in range(1, max_page + 1):
url = f'{BASE_URL}/page/{page}/' if page > 1 else BASE_URL
print(url)
rs = session.get(url)
rs.raise_for_status()
soup = bs(rs.content, 'html.parser')
for item in soup.select('.th-item'):
title = item.select_one('.th-title').text
url = item.a['href']
items.append({
'title': title,
'url': url,
})
with open('anime-serialy.json', 'w', encoding='utf-8') as f:
json.dump(items, f, indent=4, ensure_ascii=False)
Пример результата:
[
{
"title": "Семья шпиона",
"url": "https://lordserial.live/anime-serialy/6114-semya-shpiona.html"
},
{
"title": "Клинок, рассекающий демонов",
"url": "https://lordserial.live/anime-serialy/1483-klinok-rassekayuwij-demonov.html"
},
{
"title": "Реинкарнация безработного",
"url": "https://lordserial.live/anime-serialy/5585-reinkarnaciya-bezrabotnogo.html"
},
{
"title": "Суперзлодеи",
"url": "https://lordserial.live/anime-serialy/5981-superzlodei.html"
},
{
"title": "Звёздные войны: Видение",
"url": "https://lordserial.live/anime-serialy/5903-zvezdnye-voyny-videnie.html"
},
{
"title": "Повесть о конце света",
"url": "https://lordserial.live/anime-serialy/5877-povest-o-konce-sveta.html"
},
...
Автор решения: Дмитрий
→ Ссылка
Вот ещё вариант:
import requests
from bs4 import BeautifulSoup
from time import sleep
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko)"
" Chrome/101.0.4951.67 Safari/537.36"}
page = int( input('сколько страниц нужно спарсить: '))
def card_film():
for page_num in range(0, page):
URL = f'https://lordserial.live/anime-serialy/page/{page_num}/'
response = requests.get(URL, headers=headers).text
soup = BeautifulSoup(response, 'lxml')
card = soup.find_all('div', class_='th-item')
for data in card:
name = data.find('div', class_='th-title').text
card_url = data.find('a', class_='th-in with-mask').get('href')
yield name, card_url
items = []
for title, url in card_film():
sleep(1)
items.append({'title': title, 'url': url,})
Это, если нужно оставить запрос на количество страниц. И не просто циклами прогонять а в функцию-генератор обернуть. Если большой объём данных будет, то при таком подходе не нужно всё это в памяти держать. Будет выдёргивать по одной паре и потом записывать. Ну и интервалы между запросами лучше ставить, так, как минимум,нагрузка на сайт меньше.
Вот результат, с одной страницы:
items = [
{'title': 'Семья шпиона', 'url': 'https://lordserial.live/anime-serialy/6114-semya-shpiona.html'},
{'title': 'Клинок, рассекающий демонов', 'url': 'https://lordserial.live/anime-serialy/1483-klinok-rassekayuwij-demonov.html'},
{'title': 'Реинкарнация безработного', 'url': 'https://lordserial.live/anime-serialy/5585-reinkarnaciya-bezrabotnogo.html'},
{'title': 'Суперзлодеи', 'url': 'https://lordserial.live/anime-serialy/5981-superzlodei.html'},
{'title': 'Звёздные войны: Видение', 'url': 'https://lordserial.live/anime-serialy/5903-zvezdnye-voyny-videnie.html'},
{'title': 'Повесть о конце света', 'url': 'https://lordserial.live/anime-serialy/5877-povest-o-konce-sveta.html'},
{'title': 'Клеймор', 'url': 'https://lordserial.live/anime-serialy/5874-kleymor.html'},
{'title': 'Убить или быть убитым', 'url': 'https://lordserial.live/anime-serialy/5873-ubit-ili-byt-ubitym.html'},
{'title': 'Да, я паук, и что с того?', 'url': 'https://lordserial.live/anime-serialy/5858-da-ya-pauk-i-chto-s-togo.html'},
{'title': 'Избранный богами', 'url': 'https://lordserial.live/anime-serialy/5857-izbrannyy-bogami.html'},
{'title': 'Властелины вселенной: Откровение', 'url': 'https://lordserial.live/anime-serialy/5852-vlasteliny-vselennoy-otkrovenie.html'},
{'title': 'Инцидент Кэмоно', 'url': 'https://lordserial.live/anime-serialy/5828-incident-kemono.html'},
{'title': 'Тресе: Защитница города', 'url': 'https://lordserial.live/anime-serialy/5794-trese-zashchitnica-goroda.html'},
{'title': 'Эдем', 'url': 'https://lordserial.live/anime-serialy/5787-edem.html'},
{'title': 'Путь домохозяина', 'url': 'https://lordserial.live/anime-serialy/5783-put-domohozyaina.html'},
{'title': 'Темный дворецкий 2', 'url': 'https://lordserial.live/anime-serialy/5781-temnyy-dvoreckiy-2.html'},
{'title': 'Темный дворецкий', 'url': 'https://lordserial.live/anime-serialy/5782-temnyy-dvoreckiy.html'},
{'title': 'Ясукэ', 'url': 'https://lordserial.live/anime-serialy/5733-yasuke.html'}
]