BeautifulSoup: извлечь атрибут из элемента?

Я попытался найти это в Stackoverflow, но не смог вписать его в свой код. Может, кто-нибудь сможет мне в этом помочь?

Я пытаюсь получить атрибуты team1, team2 и bettext из этого HTML:

<table class = "sportbet_extra_list_table" id = "mc-ga312004790">
    <tbody>
        <tr>
            <td class = "sportbet_extra_c0"></td>
            <td class = "sportbet_extra_c1"><span>
                <a class = "combi_1"></a>
                Hvem vinder kampen?                            </span></td>
            <td class = "sportbet_extra_c2">
			                <div id = "mc-ti312004790_1" class = "js-ti312004790_1 sportbet_extra_rate_content" onclick = "Bettingslip.addBet({type: 'N', team1: 'Rusland', team2: 'Saudi Arabien', bettext: 'Hvem vinder kampen?', combi_cat: 1, sub_group: 0, game: 312004790, groupId:461392, leagueId:30124, odd: 138, odd_id: 312004790, tiptext: '1', tip: 1, betstyle: 2224})">
                    <div class = "sportbet_content_rate_left">1</div>
                    <div class = "sportbet_content_rate_right">1,38</div>
                </div>
				
            </td>

Пока что я использую этот код для извлечения информации из sportbet_extra_list_table:

    REQUEST = requests.get('https://www.cashpoint.dk/en/? 
              r=bets/xtra&group=461392&game=312004790').text
    SOUP = BeautifulSoup(REQUEST, 'lxml')
    # find_all to extract all
    SCRAPE = SOUP.find('table', class_='sportbet_extra_list_table')

    for CLEAN in SCRAPE:
        CLEANER = BeautifulSoup(str(CLEAN), 'lxml').text
        STRIP = " ".join(line.strip() for line in CLEANER.split("\n"))
        print(STRIP)

Я пытался добавить

SOUP.find('table', class_='sportbet_extra_list_table', attrs = {"onclick": "team1"})

Но это не сработало

Может это поможет stackoverflow.com/questions/39289206/…

return 02.06.2018 10:42

Спасибо за ссылку. Я с трудом пытаюсь преобразовать это в мою ситуацию :( Я попробую заглянуть в 're', если не получу других ответов.

user2939562 02.06.2018 10:51
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
2
138
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вот решение вашей проблемы:

SCRAPE = SOUP.find('table', class_='sportbet_extra_list_table')
# Get the content of the onclick attribute using ['onclick']
SCRAPE = SCRAPE.find('div', id = "mc-ti312004790_1")['onclick']
# Now separate every variable in it
attrs = SCRAPE.split(',')
# Retrieve what you want
team1 = attrs[1].split(':')[1].replace(' ', '').replace('\'', '')
team2 = attrs[2].split(':')[1].replace(' ', '').replace('\'', '')
bettext = attrs[3].split(':')[1].replace(' ', '').replace('\'', '')

print(team1)
print(team2)
print(bettext)

Он выводит:

Rusland

SaudiArabien

Hvemvinderkampen?

Переменная attrs выглядит так:

["Bettingslip.addBet({type: 'N'", " team1: 'Rusland'", " team2: 'Saudi Arabien'", " bettext: 'Hvem vinder kampen?'", ' combi_cat: 1', ' sub_group: 0', ' game: 312004790', ' groupId:461392', ' leagueId:30124', ' odd: 138', ' odd_id: 312004790', " tiptext: '1'", ' tip: 1', ' betstyle: 2224})']

Переменная attrs [1]:

" team1: 'Rusland'"

выполнение .split (':') дает:

['" team1", " 'Rusland'"]

чтобы получить имя team1, возьмем attrs [1] .split (':') [1], он дает:

" 'Rusland'"

Выполнение .replace ('', '') удаляет пробелы, а выполнение .replace ('\' ',' ') удаляет "'".

Именно то, что мне нужно, с подробными объяснениями происходящего. Большое вам спасибо, N3RO!

user2939562 03.06.2018 18:49

Добро пожаловать, @ChristianHandest, удачи в вашем проекте! :)

nero 03.06.2018 21:04

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

import json
import requests 
from bs4 import BeautifulSoup

url = "https://www.cashpoint.dk/en/?r=bets/xtra&group=461392&game=312004790"

res = requests.get(url)
soup = BeautifulSoup(res.text,'lxml')

dataset = []
for items in soup.select("#container_xtra [id^='mc-ti']"):
    d = {}
    data = items.get("onclick").split("Bettingslip.addBet(")[1].split(")")[0]

    d['team1'] = data.split("team1:")[1].split(",")[0].split("'")[1].split("'")[0]
    d['team2'] = data.split("team2:")[1].split(",")[0].split("'")[1].split("'")[0]
    d['bettext'] = data.split("bettext:")[1].split(",")[0].split("'")[1].split("'")[0]
    if d not in dataset:
        dataset.append(d)

print(json.dumps(dataset,indent=4))

Частичный результат:

[
    {
        "team1": "Rusland",
        "team2": "Saudi Arabien",
        "bettext": "Hvem vinder kampen?"
    },
    {
        "team1": "Rusland",
        "team2": "Saudi Arabien",
        "bettext": "Dobbeltchance"
    },
Ответ принят как подходящий

Вы можете использовать demjson.decode() для преобразования необработанных объектов JavaScript в словари Python. Это значительно упрощает получение конкретных данных о ставке.

Код:

import re
import demjson
import requests
from bs4 import BeautifulSoup

r = requests.get('https://www.cashpoint.dk/en/'
                 '?r=bets/xtra'
                 '&group=461392'
                 '&game=312004790')

soup = BeautifulSoup(r.text, 'lxml')
tables = soup.select('table.sportbet_extra_list_table')

for table in tables:
    fields = table.select('.sportbet_extra_rate_content')
    for field in fields:
        js_obj = re.search('{.+}', field['onclick']).group()
        bet = demjson.decode(js_obj)
        print((bet['team1'], bet['team2'], bet['bettext'], bet['tiptext'], bet['tip']))

Выход:

('Rusland', 'Saudi Arabien', 'Hvem vinder kampen?', '1', 1)
('Rusland', 'Saudi Arabien', 'Hvem vinder kampen?', 'X', 3)
('Rusland', 'Saudi Arabien', 'Hvem vinder kampen?', '2', 2)
('Rusland', 'Saudi Arabien', 'Dobbeltchance', '1x', 1)
...
('Rusland', 'Saudi Arabien', 'Scorer i begge HL', 'B', 2)

Я пойду с ответом TopTo. Спасибо, что нашли время помочь!

user2939562 03.06.2018 08:28

@ChristianHandest, что не так с этим ответом? Он чистый и дает вам доступ ко всей информации о ставке. Код Topto трудно понять со всеми этими вложенными вызовами split() + там много дублирования кода.

radzak 03.06.2018 17:41

После тестирования вашего кода, кода N3RO и TopTo он закончился тем, что я использую в основном код N3RO и ваш тоже. Код N3RO немного подробнее объяснил, как перемещаться с помощью attrs, и он использовал мой код. Итак, я пошел с этим, и теперь я сижу и учусь на этом. Но когда я углублюсь в свой собственный код сейчас и продвинусь вперед, я вполне могу в конечном итоге использовать ваш, поскольку он дает мне хорошую таблицу json, которую я могу извлечь позже, и если да, я изменю "решенный" поз. Еще раз большое спасибо, Джатимир!

user2939562 03.06.2018 18:47

Другие вопросы по теме