Почему это происходит?
Ошибка возникает, когда str
используется для преобразования bytes
объекта в str
.Это не делает преобразование желаемым способом.
a = re.findall(r'<b><a[^>]* href="([^"]*)"',str(response))
# ^^^
Например, если ответом является слово «Tanıtım», то оно будет выражено в UTF-8 как b'Tan\xc4\xb1t\xc4\xb1m'
.Если затем вы используете str
для этого, вы получите:
In [1]: response = b'Tan\xc4\xb1t\xc4\xb1m'
In [2]: str(response)
Out[2]: "b'Tan\\xc4\\xb1t\\xc4\\xb1m'"
Если вы преобразуете это в JSON, вы увидите двойные обратные слеши (которые на самом деле являются обычными обратными слешами, закодированные как JSON).
In [3]: import json
In [4]: print(json.dumps(str(response)))
"b'Tan\\xc4\\xb1t\\xc4\\xb1m'"
Правильный способ преобразования объекта bytes
обратно в str
- это использование метода decode
с соответствующей кодировкой:
In [5]: response.decode('UTF-8')
Out[5]: 'Tanıtım'
Обратите внимание, что ответне действует UTF-8, к сожалению.Операторы веб-сайта, по-видимому, подают поврежденные данные.
Быстрое исправление
Замените каждый вызов на str(response)
на response.decode('UTF-8', 'replace')
и обновите регулярные выражения для соответствия.
a = re.findall(
# "r" prefix to string is unnecessary
'<b><a[^>]* href="([^"]*)"',
response.decode('UTF-8', 'replace'))
sub_req = Request('https://www.manga-tr.com/'+a[3],
headers=headers)
sub_response = urlopen(sub_req).read()
manga = {}
manga['manga'] = []
manga_subject = re.findall(
# "r" prefix to string is unnecessary
'<h3>Tanıtım</h3>([^<]*)',
sub_response.decode('UTF-8', 'replace'))
manga['manga'].append({'msubject': manga_subject })
# io.open is the same as open
with open('allmanga.json', 'w', encoding='utf-8-sig') as fp:
# json.dumps is unnecessary
json.dump(manga, fp, indent=4)
Better Fix
Использовать «Запросы»
Библиотека Запросы намного проще, чем использование urlopen
.Вам придется установить его (с помощью pip, apt, dnf и т. Д., Что бы вы ни использовали), он не поставляется с Python.Это будет выглядеть так:
response = requests.get(
'https://www.manga-tr.com/manga-list.html')
И тогда response.text
содержит декодированную строку, вам не нужно декодировать ее самостоятельно.Проще!
Использование BeautifulSoup
Библиотека Beautiful Soup может выполнять поиск в документах HTML, и она более надежна и проста в использовании, чем регулярные выражения.Это также должно быть установлено.Вы можете использовать его следующим образом, например, чтобы найти всю сводку со страницы манги:
soup = BeautifulSoup(response.text, 'html.parser')
subject = soup.find('h3', text='Tanıtım').next_sibling.string
Сводка
Вот Суть , содержащая более полноепример того, как может выглядеть скребок.
Имейте в виду, что очистка веб-сайта может быть немного трудной, просто потому, что вы можете очистить 100 страниц, а затем вдруг обнаружите, что с вашим скребком что-то не так, или выслишком сильное попадание на сайт, или что-то терпит неудачу и терпит неудачу, и вам нужно начать все сначала.Таким образом, очистка часто включает ограничение скорости, сохранение прогресса и кэширование ответов и (в идеале) синтаксический анализ robots.txt.
Но Запросы + BeautifulSoup по крайней мере получатты начал.Опять же, смотрите Gist .