Python 3 при написании json файла проблема двойной обратной косой черты - PullRequest
0 голосов
/ 26 февраля 2019

Я использую urllib.request и regex для html parse, но когда я пишу в файл json, в тексте появляется двойная косая черта.Как я могу заменить одну обратную косую черту?Я посмотрел на многие решения, но ни одно из них не сработало.

headers = {}
headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0'
req = Request('https://www.manga-tr.com/manga-list.html', headers=headers)
response = urlopen(req).read()
a = re.findall(r'<b><a[^>]* href="([^"]*)"',str(response))
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'<h3>Tan.xc4.xb1t.xc4.xb1m<.h3>[^<]*.n.t([^<]*).t',str(sub_response))
manga['manga'].append({'msubject': manga_subject })
with io.open('allmanga.json', 'w', encoding='utf-8-sig') as outfile:
outfile.write(json.dumps(manga, indent=4))

это мой файл json

{
    "manga": [
        {
            "msubject": [
                "  Minami Ria 16 ya\\xc5\\x9f\\xc4\\xb1ndad\\xc4\\xb1r. \\xc4\\xb0lk erkek arkada\\xc5\\x9f\\xc4\\xb1 sakatani jirou(16) ile yakla\\xc5\\x9f\\xc4\\xb1k 6 ayd\\xc4\\xb1r beraberdir. Herkes taraf\\xc4\\xb1ndan \\xc3\\xa7ifte kumru olarak g\\xc3\\xb6r\\xc3\\xbclmelerine ra\\xc4\\x9fmen ili\\xc5\\x9fkilerinde %1\\'lik bir eksiklik vard\\xc4\\xb1r. Bu eksikli\\xc4\\x9fi tamamlayabilecekler mi?"
        }
    ]
}

1 Ответ

0 голосов
/ 26 февраля 2019

Почему это происходит?

Ошибка возникает, когда 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 .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...