Парсинг Steam Market - PullRequest
       123

Парсинг Steam Market

0 голосов
/ 28 мая 2020

У меня есть ссылка

И в конце есть "_price_as c", это делает сортировку по возрастанию. когда я перехожу по этой ссылке в браузере, сортировка работает нормально.

screenshot1

Но! Если я попытаюсь разобрать ссылки на товары с помощью bs4, это даст мне товары со случайными ценами, т.е. сортировка по возрастанию не работает

screenshot2

что я делаю не так?

from urllib.request import urlopen
from bs4 import BeautifulSoup

link = 'https://steamcommunity.com/market/search?q=&category_730_ItemSet%5B%5D=any&category_730_ProPlayer%5B%5D=any&category_730_StickerCapsule%5B%5D=any&category_730_TournamentTeam%5B%5D=any&category_730_Weapon%5B%5D=any&category_730_Type%5B%5D=tag_CSGO_Type_Knife&appid=730#p1_price_asc'

total_links = ''

page = urlopen(link)
bs_page = BeautifulSoup(page.read(), features="html.parser")
objects = bs_page.findAll(class_="market_listing_row_link")

for g in range(10):
    total_links += str(objects[g]["href"]) + '\n'
print(total_links)

Ответы [ 2 ]

2 голосов
/ 28 мая 2020

Причина, по которой это происходит, заключается в том, что если вы посмотрите на следующую ссылку

https://steamcommunity.com/market/search?q=&category_730_ItemSet%5B%5D=any&category_730_ProPlayer%5B%5D=any&category_730_StickerCapsule%5B%5D=any&category_730_TournamentTeam%5B%5D=any&category_730_Weapon%5B%5D=any&category_730_Type%5B%5D=tag_CSGO_Type_Knife&appid=730#p1_price_asc

, ссылка заканчивается на « # p1_price_as c» , хэштег является индикатором своего рода маркера страницы, вот ссылка , которая дает подробное объяснение. Обычно "#" в URL-адресе обычно вызывается функциями javascript.

Поскольку вы загружаете страницу, используя:

page = urlopen(link)

Это не приводит к вызовам функций javascript это делает сортировку. Я настоятельно рекомендую ссылку на хэштег, поскольку она объясняет намного лучше, чем я. 1019 *

Используйте библиотеку селена, поскольку она имитирует браузер Продолжайте использовать то, что вы используете, и вручную сортируйте данные самостоятельно (это тривиально, и вы узнаете больше)

Я бы лично порекомендовал метод 2, так как изучение селена может быть занозой в заднице и обычно не стоит того ... на мой взгляд.

1 голос
/ 28 мая 2020

Эта страница использует JavaScript для получения отсортированных данных, но BeautifulSoup / urllib не может работать JavaScript

Но используя DevTools в Firefox / Chrome (tab: Network, фильтр: XHR) Я обнаружил, что JavaScript читает JSON данные с некоторого URL-адреса, а есть HTML с отсортированными данными, поэтому вы можете использовать этот URL-адрес с BeautifulSoup для получения отсортированных данных.

from urllib.request import urlopen
from bs4 import BeautifulSoup
import json

# new url 

link = 'https://steamcommunity.com/market/search/render/?query=&start=0&count=10&search_descriptions=0&sort_column=price&sort_dir=asc&appid=730&category_730_ItemSet%5B%5D=any&category_730_ProPlayer%5B%5D=any&category_730_StickerCapsule%5B%5D=any&category_730_TournamentTeam%5B%5D=any&category_730_Weapon%5B%5D=any&category_730_Type%5B%5D=tag_CSGO_Type_Knife'

page = urlopen(link)

data = json.loads(page.read().decode())
html = data['results_html']

bs_page = BeautifulSoup(html, features="html.parser")
objects = bs_page.findAll(class_="market_listing_row_link")

data = []

for g in objects:
    link  = g["href"]
    price = g.find('span', {'data-price': True}).text
    data.append((price, link))

print("\n".join(f"{price} | {link}" for price, link in data))

Результат:

$67.43 USD | https://steamcommunity.com/market/listings/730/%E2%98%85%20Navaja%20Knife%20%7C%20Urban%20Masked%20%28Field-Tested%29
$67.70 USD | https://steamcommunity.com/market/listings/730/%E2%98%85%20Navaja%20Knife%20%7C%20Night%20Stripe%20%28Field-Tested%29
$69.00 USD | https://steamcommunity.com/market/listings/730/%E2%98%85%20Navaja%20Knife%20%7C%20Night%20Stripe%20%28Minimal%20Wear%29
$69.52 USD | https://steamcommunity.com/market/listings/730/%E2%98%85%20Navaja%20Knife%20%7C%20Scorched%20%28Battle-Scarred%29
$69.48 USD | https://steamcommunity.com/market/listings/730/%E2%98%85%20Navaja%20Knife%20%7C%20Safari%20Mesh%20%28Field-Tested%29
$70.32 USD | https://steamcommunity.com/market/listings/730/%E2%98%85%20Navaja%20Knife%20%7C%20Forest%20DDPAT%20%28Battle-Scarred%29
$70.90 USD | https://steamcommunity.com/market/listings/730/%E2%98%85%20Navaja%20Knife%20%7C%20Night%20Stripe%20%28Well-Worn%29
$70.52 USD | https://steamcommunity.com/market/listings/730/%E2%98%85%20Navaja%20Knife%20%7C%20Forest%20DDPAT%20%28Field-Tested%29
$71.99 USD | https://steamcommunity.com/market/listings/730/%E2%98%85%20Navaja%20Knife%20%7C%20Boreal%20Forest%20%28Field-Tested%29
$72.08 USD | https://steamcommunity.com/market/listings/730/%E2%98%85%20Navaja%20Knife%20%7C%20Scorched%20%28Field-Tested%29

BTW: Вот моя первая версия, которая читалась со старого URL-адреса и сортировалась по Python. Но он может сортировать данные только на первой странице. Чтобы получить лучший результат, ему пришлось бы прочитать все страницы - а это заняло бы много времени.

from urllib.request import urlopen
from bs4 import BeautifulSoup

link = 'https://steamcommunity.com/market/search?q=&category_730_ItemSet%5B%5D=any&category_730_ProPlayer%5B%5D=any&category_730_StickerCapsule%5B%5D=any&category_730_TournamentTeam%5B%5D=any&category_730_Weapon%5B%5D=any&category_730_Type%5B%5D=tag_CSGO_Type_Knife&appid=730#p1_price_asc'
page = urlopen(link)

bs_page = BeautifulSoup(page.read(), features="html.parser")
objects = bs_page.findAll(class_="market_listing_row_link")

data = []

for g in objects:
    link  = g["href"]
    price = g.find('span', {'data-price': True})['data-price']
    price = int(price)
    data.append((price,link))

data = sorted(data)

print("\n".join(f"${price/100} USD | {link}" for price, link in data))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...