Выполнение JS с использованием Python и сохранение результатов в массиве

#javascript #python #html #web-scraping

#javascript #python #HTML #веб-очистка

Вопрос:

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

введите описание изображения здесь

Чтобы получить результат фильтра на карте (страны, окрашенные синим цветом), я выполняю этот фрагмент javascript :

 var n = $("input[name=adoptionStatus]:checked").val();
    (n == undefined || n === "") amp;amp; (n = "00000000000000000000000000000000");
    $(".status-text").hide();
    $("#"   n).show();
    $("#vmap").vectorMap("set", "colors", resetColorsData);
    resetColorsData = {};
    colorsData = {};
    $("#countries_list a").each(function(t, i) {
        $(i).data("adoption-status").indexOf(n) >= 0 amp;amp; (colorsData[$(i).data("country-code")] = "#2f98cb", resetColorsData[$(i).data("country-codecountry-code")] = "#fefefe")
    });
    $("#vmap").vectorMap("set", "colors", colorsData)
 

Переменная n используется для хранения значения переключателя, как в этом случае cae64c6b731d47cca7565b2a74d11d53 :

 <div class="map-filter-radio radio">
            <label>
                <input type="radio" name="adoptionStatus" alt="IFRS Standards are permitted, but not required, for use by at least some domestic publicly accountable entities, including listed companies and financial institutions." title="IFRS Standards are permitted, but not required, for use by at least some domestic publicly accountable entities, including listed companies and financial institutions." value="cae64c6b731d47cca7565b2a74d11d53">
                IFRS Standards are permitted but not required for domestic public companies
            </label>
</div>
 

Когда я запускаю Javascript в консоли и пытаюсь получить colorsData , я получаю список стран, окрашенных в синий цвет, как показано ниже :

 bm: "#2f98cb"
ch: "#2f98cb"
gt: "#2f98cb"
iq: "#2f98cb"
jp: "#2f98cb"
ky: "#2f98cb"
mg: "#2f98cb"
ni: "#2f98cb"
pa: "#2f98cb"
py: "#2f98cb"
sr: "#2f98cb"
tl: "#2f98cb"
 

введите описание изображения здесь

Как я могу выполнить скрипт JS на веб-странице и получить результат использования цветных стран в массиве python ?

Комментарии:

1. Есть ли причина, по которой вы не используете более читаемый if ( ... ) { ... } вместо этих (имхо ужасных) ... amp;amp; ... / ... amp;amp; ... , ... однострочных?

2. @Andreas Я получил скрипт с веб-сайта. Это не моя работа

Ответ №1:

Просмотрев список стран, указанных #countries_list , вы получили список a тегов, подобных следующему :

 <a id="country_bd" data-country-code="bd" data-adoption-status="97f9b22998d546f7856bb1b4f0586521|3adc18f07ff64c908a6d835e08344531|ff784361818644798ea899f81b8b6d61" href="/use-around-the-world/use-of-ifrs-standards-by-jurisdiction/bangladesh/">
    <img src="/-/media/7bfd06a698594c2cb3614578a41caa9e.ashx" alt="Bangladesh">
    Bangladesh
</a>
 

data-adoption-status Атрибут представляет собой список adoptionStatus , разделенный | символом .

Вам просто нужно разделить их и сопоставить только те страны, которые ссылаются на значение из input adoptionValue следующим образом :

 if selectedAdoptionStatus in t["data-adoption-status"].split("|")
 

Следующий код перечисляет все input теги и извлекает adoptionStatus для каждого из них, он предлагает пользователю выбрать фильтр (от 0 до 4) и получает выбранные страны путем фильтрации по data-adoption-status атрибуту :

 import requests
from bs4 import BeautifulSoup

r = requests.get("https://www.ifrs.org/use-around-the-world/use-of-ifrs-standards-by-jurisdiction/")
soup = BeautifulSoup(r.text, "html.parser")

choiceContainer = soup.find("div", {"class":"map-filters"})

choices = [
    (t["title"], t["value"])
    for t in choiceContainer.findAll("input")
]

for idx, choice in enumerate(choices):
    print(f"[{idx}] {choice[0]}")
val = input("Choose a filter index : ") 
choice = choices[int(val)]

print(f"You have chosen {choice[0]}")

selectedAdoptionStatus = choice[1]

countryList = soup.find("div", {"id":"countries_list"})
selectedCountries = [
    {
        "countryCode": t["data-country-code"],
        "adoptionStatus": t["data-adoption-status"].split("|"),
        "link": t["href"],
        "country": t.find("img")["alt"]
    }
    for t in countryList.findAll("a")
    if selectedAdoptionStatus in t["data-adoption-status"].split("|")
]

for it in selectedCountries:
    print(it["country"])
 

запустите этот код на repl.it


Пример вывода

 [0] IFRS Standards are required for use by all or most domestic publicly accountable entities.
[1] IFRS Standards are permitted, but not required, for use by at least some domestic publicly accountable entities, including listed companies and financial institutions.
[2] IFRS Standards are required or permitted for use by foreign securities issuers.
[3] In most cases an SME may also choose full IFRS Standards. In some cases, an SME may also choose local standards for SMEs.
[4] The body with authority to adopt financial reporting standards is actively studying whether to adopt the <em>IFRS for SMEs</em> Standard.
Choose a filter index : 1
You have chosen IFRS Standards are permitted, but not required, for use by at least some domestic publicly accountable entities, including listed companies and financial institutions.
Bermuda
Cayman Islands
Guatemala
Iraq
Japan
Madagascar
Nicaragua
Panama
Paraguay
Suriname
Switzerland
Timor-Leste