Парсинг названия игры, содержащего «@»: парсер распознает такое имя как адрес электронной почты

Я хочу собрать информацию об играх. Однако название некоторых игр содержит «@», например игра «Ampers@t».

Когда я пытаюсь очистить название таких игр, код возвращает мне «[email protected]». Видимо, мой код не распознает, что это название игры, а не электронная почта.

Здесь используются мои коды.

import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
from bs4 import BeautifulSoup
session = requests.Session()
retry = Retry(connect=3, backoff_factor=0.5)
adapter = HTTPAdapter(max_retries=retry)
session.mount("http://", adapter)
session.mount("https://", adapter)

def grab_soup(url):
    """Takes a url and returns a BeautifulSoup object"""
    response = session.get(url, headers = {"User-Agent": "Mozilla/5.0"})
    assert response.status_code == 200, "Problem with url request! %s throws %s" % (
        url,
        response.status_code,
    )  # checking that it worked
    page = response.text
    soup = BeautifulSoup(page, "lxml")
    return soup

soup = grab_soup("https://www.mobygames.com/game/amperst")

header = soup.find(class_ = "niceHeaderTitle")("a")

Я ожидаю, что вывод заголовка

<a href = "https://www.mobygames.com/game/amperst">Ampers@t</a>,
...

Однако вывод:

<a href = "https://www.mobygames.com/game/amperst"><span class = "__cf_email__" data-cfemail = "ce8fa3beabbcbd8eba">[email protected]</span></a>,
...

И я пытаюсь проверить источник страницы игры. Действительно, исходник страницы записывается так:

<div class = "rightPanelHeader">
<h1 class = "niceHeaderTitle">
<a href = "https://www.mobygames.com/game/amperst">
<span class = "__cf_email__" data-cfemail = "cd8ca0bda8bfbe8db9">[email&#160;protected]
</span>
</a>"

Поэтому причина, по которой мой код дает мне контент, вероятно, заключается в том, что он записывается в источнике страницы. Но есть ли способ избавиться от этой проблемы?

Я нашел это решение. Но это нежелательно для меня, так как у меня есть много игр, которые нужно очистить, и я не могу запустить код для каждой из них.

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

Driftr95 26.11.2022 02:23

@ Driftr95 У меня есть много игр (около 10 000), которые нужно очистить. Только некоторые из них содержат @ в своих именах. Поэтому я думаю, что запускать функцию декодирования для каждого из них может быть неэффективно. Таким образом, это своего рода требование скорости.

Xiaowei Zhang 26.11.2022 12:36

почему бы не сделать это условно? что-то вроде for i, h in enumerate(header): if h.get_text() == '[email protected]' and h.get('data-cfemail'): header[i].string = deCFEmail(h.get('data-cfemail')) не должно добавлять столько времени

Driftr95 26.11.2022 13:08
Почему в 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 может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
3
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

[Расширено из моего комментария] Если вы немного подправите функцию из этого ответа, чтобы

def deCFEmail(encTag):
    if not (encTag.get('data-cfemail') or encTag.select('*[data-cfemail]')):
        encTag.append(f'[! no "data-cfemail" attribute !]')
    else:
        fp = encTag.get('data-cfemail', None)
        if fp is None:
            fp = encTag.select_one('*[data-cfemail]').get('data-cfemail')
        try:
            r = int(fp[:2],16)
            encTag.string = ''.join([chr(int(fp[i:i+2], 16) ^ r) for i in range(2, len(fp), 2)]) 
        except Exception as e:
            encTag.append(f'! failed to decode "{e}"')
    return encTag

то вы можете использовать его условно:

for i, h in enumerate(header): 
    if h.get_text()=='[email\xa0protected]': 
        header[i] = deCFEmail(h)

Итак, header может идти от

[<a href = "https://www.mobygames.com/game/amperst"><span class = "__cf_email__" data-cfemail = "8ecfe3feebfcfdcefa">[email protected]</span></a>,
 <a class = "btn btn-xs btn-clear" href = "https://www.mobygames.com/game/amperst/forums">Discuss</a>,
 <a class = "btn btn-xs btn-clear" href = "https://www.mobygames.com/game/sheet/review_game/amperst/">Review</a>,
 <a class = "btn btn-xs btn-clear" href = "https://www.mobygames.com/game/amperst/add-to-want-list">+ Want</a>,
 <a class = "btn btn-xs btn-clear" href = "https://www.mobygames.com/game/amperst/add-to-have-list">+ Have</a>,
 <a class = "btn btn-xs btn-mobysuccess" href = "https://www.mobygames.com/game/amperst/contribute">Contribute</a>]

к

[<a href = "https://www.mobygames.com/game/amperst">Ampers@t</a>,
 <a class = "btn btn-xs btn-clear" href = "https://www.mobygames.com/game/amperst/forums">Discuss</a>,
 <a class = "btn btn-xs btn-clear" href = "https://www.mobygames.com/game/sheet/review_game/amperst/">Review</a>,
 <a class = "btn btn-xs btn-clear" href = "https://www.mobygames.com/game/amperst/add-to-want-list">+ Want</a>,
 <a class = "btn btn-xs btn-clear" href = "https://www.mobygames.com/game/amperst/add-to-have-list">+ Have</a>,
 <a class = "btn btn-xs btn-mobysuccess" href = "https://www.mobygames.com/game/amperst/contribute">Contribute</a>]

это своего рода требование скорости

Дополнительное время мало чем отличается от добавления дополнительного оператора find; и в любом случае это будет незначительно по сравнению со временем парсинга (для soup = BeautifulSoup(page, "lxml")).

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