【问题标题】:Steam market parsingSteam市场解析
【发布时间】:2020-09-15 06:29:24
【问题描述】:

我有一个link

它最后有“_price_asc”,它进行升序排序。当我在浏览器中点击此链接时,排序工作正常。

但是!如果我尝试使用 bs4 解析项目链接,这会给我随机价格的项目,即升序排序不起作用

我做错了什么?

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)

【问题讨论】:

  • 此页面使用 JavaScript 对表格中的数据进行排序,但 BeautifulSoup/urllib 无法运行 JavaScript。您可能需要Selenium 来控制可以运行 JavaScript 的真实网络浏览器。或者获取所有数据和价格并使用 Python sort()sorted() 对其进行排序。
  • 我考虑过排序,这需要很多时间,但是好的,谢谢你的回答
  • 排序不会花费这么长时间 - 如果您将数据保留为(price, link),那么sort() 将按price 对其进行排序,因为它是第一个。
  • 我找到了提供排序数据的 url - 所以它不需要 Selenium,也不需要读取所有页面并在 Python 中排序。看我的回答。

标签: python parsing beautifulsoup steam


【解决方案1】:

发生这种情况的原因是因为如果您查看以下链接

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_asc" 结尾,主题标签是某种页面标记的指示符,这里有一个 link 给出了完整的解释。基本上,url中的“#”通常由javascript函数调用。

由于您正在使用以下方式下载页面:

page = urlopen(link)

这不会导致执行排序的 javascript 函数调用。我强烈推荐主题标签上的链接,因为它在解释方面比我做得更好。


现在关于如何实现你想要的,你有两个选择:

  1. 使用 selenium 库来模拟浏览器
  2. 继续使用您正在使用的数据,并自己手动对数据进行排序(这很简单,您将了解更多信息)

我个人会推荐方法 2,因为学习 selenium 可能有点让人头疼,而且通常不值得……在我看来。

【讨论】:

    【解决方案2】:

    此页面使用 JavaScript 获取排序数据,但 BeautifulSoup/urllib 无法运行 JavaScript

    但是在Firefox/Chrome中使用DevTools(标签:Network,过滤器:XHR)我发现JavaScript从某个url读取JSON数据,并且有带有排序数据的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
    

    顺便说一句:这是我的第一个版本,它从旧网址读取并在 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))
    

    【讨论】:

    • 哇,你真的为我做了所有的工作,再次感谢您的解释
    猜你喜欢
    • 2016-02-21
    • 2016-03-12
    • 1970-01-01
    • 2014-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-18
    • 2014-10-17
    相关资源
    最近更新 更多