Скребковый Javascript-рендеринг элементов веб-страницы в Selenium - PullRequest
0 голосов
/ 16 октября 2019

Я собираюсь очистить данные, которые подают SVG-элементы этой страницы:

https://www.beinsports.com/au/livescores/match-center/2019/23/1074885

Страница выглядит как Javascript, поэтому традиционное использование BeautifulSoup в Pythonне работает. Я обновил в Inspect Network XHR, и на странице не отображаются данные также в формате JSON. Однако при обновлении страницы JS в сети я вижу F24_8.js, который в предварительном просмотре показывает именно то, что я хотел бы захватить при подаче элементов SVG:

F24_8.js

Есть ли способ запустить сценарий из селена в качестве примера, чтобы имитировать рендеринг javascript и извлекать данные бэкенда здесь?

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

from bs4 import BeautifulSoup
from selenium.webdriver.support.ui import Select
from selenium.webdriver.support.ui import WebDriverWait
import selenium
from selenium import webdriver
import re
import math
import time

games=[]

browser = webdriver.PhantomJS()
browser.get("http://www.squawka.com/match-results")
WebDriverWait(browser,10)

mySelect = Select(browser.find_element_by_id("league-filter-list"))
mySelect.select_by_visible_text("German Bundesliga")

seasons=['Season 2012/2013','Season 2013/2014','Season 2014/2015','Season 2015/2016','Season 2016/2017','Season 2017/2018']
for season in seasons:
    nextSelect = Select(browser.find_element_by_id("league-season-list"))
    nextSelect.select_by_visible_text(season)

    source=browser.page_source
    soup=BeautifulSoup(source,'html.parser')
    games.extend([a.get('href') for a in soup.find_all('a',attrs={'href':re.compile('matches')})])

    pages=math.ceil(float(soup.find('span',{'class':'displaying-num'}).get_text().split('of')[-1].strip())/30)
    for page in range(2,int(pages)+1):
        browser.find_element_by_xpath('//a[contains(@href,"pg='+str(page)+'")]').click()
        source=browser.page_source
        soup=BeautifulSoup(source,'html.parser')
        games.extend([a.get('href') for a in soup.find_all('a',attrs={'href':re.compile('matches')})])

    print '---------\n'+season+' Games Appended'

import pandas as pd
import numpy as np
import lxml.etree as etree

frames=[]
count=0
for game in g2:

    try:
        url = game

        browser = webdriver.PhantomJS()
        browser.get(url)

        time.sleep(10)

        page = browser.execute_script('return new XMLSerializer().serializeToString(squawkaDp.xml);')
        root = etree.XML(page.encode('utf-8'))

        #events
        gm=pd.DataFrame()
        for f in root.iter('filters'):
            for a in f:
                for event in a.iter('event'):

                    d=event.attrib
                    records=dict((x,[y]) for x,y in d.items())
                    new_records=dict((x.tag,[x.text]) for x in event)

                    r=pd.DataFrame(records)
                    nr=pd.DataFrame(new_records)
                    j=r.join(nr)
                    j['category']=a.tag

                    gm=gm.append(j)

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

1 Ответ

0 голосов
/ 16 октября 2019

Если вы используете Selenium, вы можете использовать driver.execute_script("your script here") для запуска Javascript на странице.

Я использовал это только с очень короткими сценариями, такими как arguments[0].click();, с успехом, но я неубедитесь, как это будет работать для более длинных сценариев.

driver = new webdriver.Chrome()

driver.execute_script("your script here")

Вы также можете запускать сценарии для WebElements, используя arguments[0] в Javascript.

my_element = driver.find_element_by_xpath("//div[text()='someText']")

driver.execute_script("arguments[0].click();", my_element)

Это передаст my_element вфункция JS как this.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...