Не работает пагинация при парсинге python
Пирасинге торговой площадки steam с толкнулся с проблемой. Все страницы написанный под тегом span. Я решил перебором подставлять номера страницы в сслыку, получается https://steamcommunity.com/market/searchq=&category_570_Hero%5B%5D=any&category_570_Slot%5B%5D=any&category_570_Type%5B%5D=any&appid=570#p(1, 2, 3 и т.д)_popular_desc . Но если я вставляю ссылку 3 страницы с номером страницы, у меня всегда парсится первая страница. Код предоставляю отрезок кода и результаты работы программы. В csv всегда записывается первая страница.
import requests
from bs4 import BeautifulSoup
import csv
def get_data(url):
headers = {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36"
}
req = requests.get(url, headers = headers)
with open("index.html", 'w', encoding="utf-8") as file:
file.write(req.text)
with open("index.html", "r", encoding='utf-8') as file:
src = file.read()
arr = []
soup = BeautifulSoup(src, "lxml")
all_links = soup.find_all('a', class_ = 'market_listing_row_link')
for link in all_links:
arr.append(link.get("href"))
arr.append(link.find("span", class_ = "market_listing_item_name").text)
arr.append(link.find("span", class_ = "market_listing_game_name").text)
arr.append(link.find("span", class_ = "market_table_value normal_price").find('span', class_= "normal_price").text)
arr.append(" ")
with open("links.csv", "w") as file:
csv_writer = csv.writer(file)
for links in arr:
csv_writer.writerow([links])
for page in range(1, 4):
url = f"https://steamcommunity.com/market/search?q=&category_570_Hero%5B%5D=any&category_570_Slot%5B%5D=any&category_570_Type%5B%5D=any&appid=570#p{page}_popular_desc"
get_data(url)
Ответы (1 шт):
from requests_html import HTMLSession
from bs4 import BeautifulSoup
import csv
def get_data(url):
session = HTMLSession()
req = session.get(url)
req.html.render()
arr = []
soup = BeautifulSoup(req.html.html, "lxml")
all_links = soup.find_all('a', class_ = 'market_listing_row_link')
for link in all_links:
arr.append(link.get("href"))
arr.append(link.find("span", class_ = "market_listing_item_name").text)
arr.append(link.find("span", class_ = "market_listing_game_name").text)
arr.append(link.find("span", class_ = "market_table_value normal_price").find('span', class_= "normal_price").text)
arr.append(" ")
#UPD: для добавления вместо перезаписи можно использовать флаг "а"
with open("links.csv", "a") as file:
csv_writer = csv.writer(file)
for links in arr:
csv_writer.writerow([links])
for page in range(1, 4):
url = f"https://steamcommunity.com/market/search?q=&category_570_Hero%5B%5D=any&category_570_Slot%5B%5D=any&category_570_Type%5B%5D=any&appid=570#p{page}_popular_desc"
get_data(url)
Все потому что на странице скорее всего js, который подгружает новый список. Если вы перейдете на третью страницу в браузере, вы увидите, что сначала загрузилась первая, а потом js подгружает третью.
Здесь используется другая библиотека requests-html, у объекта класса HTMLSession есть метод render, который позволяет как раз загрузить динамический контент. У этого метода можно передавать кейворд sleep со значением в секундах, так будет подольше, но вероятнее, что точно получите свои данные.
Еще можно создавать только одну сессию вне функции и использовать константно, но у меня не получилось, видимо, не лохи valve)