Я хочу собрать информацию об играх. Однако название некоторых игр содержит «@», например игра «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 protected]
</span>
</a>"
Поэтому причина, по которой мой код дает мне контент, вероятно, заключается в том, что он записывается в источнике страницы. Но есть ли способ избавиться от этой проблемы?
Я нашел это решение. Но это нежелательно для меня, так как у меня есть много игр, которые нужно очистить, и я не могу запустить код для каждой из них.
@ Driftr95 У меня есть много игр (около 10 000), которые нужно очистить. Только некоторые из них содержат @ в своих именах. Поэтому я думаю, что запускать функцию декодирования для каждого из них может быть неэффективно. Таким образом, это своего рода требование скорости.
почему бы не сделать это условно? что-то вроде 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'))
не должно добавлять столько времени
[Расширено из моего комментария] Если вы немного подправите функцию из этого ответа, чтобы
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")
).
Видимо, мой код не распознает, что это название игры, а не электронная почта" - это не так, вы сказали, что это так в исходнике страницы, так что это не имеет отношения к вашему коду, так как он не получает расшифрованное электронное письмо в первую очередь .... но почему вы не можете включить эту функцию декодирования в свой код парсера? Есть ли требования к скорости?