BeautifulSoup не возвращается Twitch.tv Viewcount - PullRequest
0 голосов
/ 06 октября 2018

Я пытаюсь почистить зрителей на www.twitch.tv/directory, используя Python.Я попробовал базовый скрипт BeautifulSoup:

url= 'https://www.twitch.tv/directory'
html= urlopen(url)
soup = BeautifulSoup(url, "html5lib") #also tried using html.parser, lxml
soup.prettify()

Это дает мне HTML без показанных фактических чисел зрителя.

Затем я попытался использовать данные param ajax. Из этой темы

param = {"action": "getcategory",
        "br": "f21",
        "category": "dress",
        "pageno": "",
        "pagesize": "",
        "sort": "",
        "fsize": "",
        "fcolor": "",
        "fprice": "",
        "fattr": ""}

url = "https://www.twitch.tv/directory"
# Also tried with the headers parameter headers={"User-Agent":"Mozilla/5.0...
js = requests.get(url,params=param).json()

Но я получаю JSONDecodeError: Expecting value: line 1 column 1 (char 0) ошибку.

С тех пор я перешел к селену

driver = webdriver.Edge()
url = 'https://www.twitch.tv/directory'
driver.get(url)
#Also tried driver.execute_script("return document.documentElement.outerHTML") and innerHTML
html = driver.page_source
driver.close()
soup = BeautifulSoup(html, "lxml")

Этипросто получите тот же результат, который я получаю от стандартного вызова BeautifulSoup.

Буду признателен за любую помощь в очистке счетчика просмотров.

1 Ответ

0 голосов
/ 06 октября 2018

Статистика отсутствует на странице при первой загрузке.Страница отправляет запрос graphql на https://gql.twitch.tv/gql для получения игровых данных.Когда пользователь не вошел в систему, запрос graphql запрашивает запрос AnonFrontPage_TopChannels.

Вот рабочий запрос на python:

import requests
import json

resp = requests.post(
    "https://gql.twitch.tv/gql",
    json.dumps(
        {
            "operationName": "AnonFrontPage_TopChannels",
            "variables": {"platformType": "all", "isTagsExperiment": True},
            "extensions": {
                "persistedQuery": {
                    "version": 1,
                    "sha256Hash": "d94b2fd8ad1d2c2ea82c187d65ebf3810144b4436fbf2a1dc3af0983d9bd69e9",
                }
            },
        }
    ),
    headers = {'Client-Id': 'kimne78kx3ncx6brgo4mv6wki5h1ko'},
)

print(json.loads(resp.content))

Я включил Client-Idв запросе.Идентификатор не кажется уникальным для сессии, но я думаю, что Twitch истекает их, так что это, вероятно, не будет работать вечно.Вам нужно будет проверить будущие запросы graphql и в будущем получить новый Client-Id или выяснить, как программно очистить один из них со страницы.

Этот запрос фактически является разделом Top Live Channels.Вот как вы можете получить количество просмотров и заголовки:

edges = json.loads(resp.content)["data"]["streams"]["edges"]
games = [(f["node"]["title"], f["node"]["viewersCount"]) for f in edges]

# games:
[
    ("Let us GAME", 78250),
    ("(REBROADCAST) Worlds Play-In Knockouts: Cloud9 vs. Gambit Esports", 36783),
    ("RuneFest 2018 - OSRS Reveals !schedule", 35042),
    (None, 25237),
    ("Front Page of TWITCH + Fortnite FALL SKIRMISH Training!", 22380),
    ("Reckful - 3v3 with barry and a german", 20399),
]

Вам нужно будет проверить Chrome Network Inspector и выяснить структуру других запросов, чтобы получить больше данных.

А вот пример для страницы каталога:

import requests
import json

resp = requests.post(
    "https://gql.twitch.tv/gql",
    json.dumps(
        {
            "operationName": "BrowsePage_AllDirectories",
            "variables": {
                "limit": 30,
                "directoryFilters": ["GAMES"],
                "isTagsExperiment": True,
                "tags": [],
            },
            "extensions": {
                "persistedQuery": {
                    "version": 1,
                    "sha256Hash": "75fb8eaa6e61d995a4d679dcb78b0d5e485778d1384a6232cba301418923d6b7",
                }
            },
        }
    ),
    headers={"Client-Id": "kimne78kx3ncx6brgo4mv6wki5h1ko"},
)

edges = json.loads(resp.content)["data"]["directoriesWithTags"]["edges"]
games = [f["node"] for f in edges]
...