Я использую Selenium (Chromedriver) с Python 2.7, чтобы очистить сайт от динамического текста, который отображается в тегах. Внутри находится HTML-код, вложенный в объект JSON, который используется для создания списка содержимого на странице, которую я просматриваю, но меня интересует только получение текстового содержимого. Мне удалось выяснить, как очистить теги HTML, используя re
, но текст по-прежнему содержит коды символов HTML для специальных символов, которые я хочу заменить символом, которому они соответствуют.
Так, например, скажем, мой json (после очистки HTML-тегов) выглядит следующим образом:
[
{
"data": {
"published_on": "2019-01-15T08:46:00+00:00",
"id": "somealphanumericid",
"short_description": "Albert Einstein’s Theory of Relativity: Should We Worry…?",
"series": "Science",
"long_description": "Albert Einstein does an interview with Mr. John Smith about the application of the theory of relativity, and what it could mean for the future of the pizza industry!",
"duration": "752000",
"type": "video",
"title": "Albert Einstein’s Theory of Relativity:"
},
"links": {
"permalink": "https://www.stackoverflow.com"
},
"key": "somealphanumericid"
},
...
]
Редактировать: Объект JSON на самом деле является массивом объектов JSON, следовательно, []
. Сайт, который я копирую, разбит на страницы, поэтому я получаю JSON с каждой страницы и в конце просто объединяю их в один массив, чтобы с ним было легче работать.
Вы можете видеть, что такие символы, как точки, запятые, двоеточия и т. Д., Очищаются как соответствующие им коды символов HTML.
Теперь я перебираю JSON и помещаю все в базу данных sqlite, поэтому не имеет значения, заменяю ли я коды символов в самом JSON или выполняю замену прямо перед тем, как помещать данные в дб.
Первое, что я попытался сделать, это использовать вторичную функцию, которая взяла строку в качестве аргумента и вернула строку с замененными символами. Я в основном изменил решение, которое можно найти здесь . Итак, эта функция была:
from BeautifulSoup import BeautifulStoneSoup
def HTMLEntitiesToUnicode(text):
text = unicode(BeautifulStoneSoup(text, convertEntities=BeautifulStoneSoup.ALL_ENTITIES))
return text
Я использовал это в цикле, который создает набор данных для строки данных, которые должны быть переданы в sqlite следующим образом:
def json_to_rows(json_file):
with open(json_file, 'r') as infile:
data = json.load(infile)
data_as_rows = []
length = len(data)
for i in range(0, length, 1):
data_as_rows.append((
data[i]['key'],
data[i]['data']['id'],
data[i]['links']['permalink'],
HTMLEntitiesToUnicode(data[i]['data']['series']),
HTMLEntitiesToUnicode(data[i]['data']['title']),
data[i]['data']['published_on'],
data[i]['data']['type'],
data[i]['data']['duration'],
HTMLEntitiesToUnicode(data[i]['data']['short_description']),
HTMLEntitiesToUnicode(data[i]['data']['long_description']),
))
return data_as_rows
Однако это привело к следующей ошибке при разборе HTMLEntitiesToUnicode(data[i]['data']['series'])
:
File "BeautifulSoup.py", line 1918, in _detectEncoding
'^<\?.*encoding=[\'"](.*?)[\'"].*\?>').match(xml_data)
TypeError: expected string or buffer
Я не могу понять, почему BeautifulSoup не видит это как строку, но я попытался изменить ее на:
HTMLEntitiesToUnicode(str(data[i]['data']['series']))
Что тогда дало мне ошибку:
File "support.py", line 162, in json_to_rows
HTMLEntitiesToUnicode(str(data[i]['data']['series'])),
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2019' in position 129: ordinal not in range(128)
Добавление .encode('utf-8')
также не устраняет ошибку (это было рекомендовано для других сообщений с таким же сообщением об ошибке).
Моя конечная цель - просто собрать всю эту информацию в БД, чтобы она была отформатирована как обычный разборчивый текст (кроме длительности, которая в любом случае имеет тип INTEGER
).
Я хотел бы сделать замену символов до / после подачи данных в БД, но также возможно, что я могу перебирать БД в отдельной функции и очищать ее, хотя это выглядит как гораздо менее эффективный способ сделать это.