Проблема с заменой тегов на новую строку с помощью bs4
Проблема: я не могу заменить <br>
теги с символом новой строки, используя Beautiful Soup 4.
Код: Моя программа (соответствующая часть) в настоящее время выглядит
for br in board.select('br'):
br.replace_with('\n')
но я также пытался board.find_all()
на месте board.select()
,
Результаты: Когда я использую board.replace_with('\n')
все <br>
теги заменяются строковым литералом \n
, Например, <p>Hello<br>world</p>
в конечном итоге станет Hello\nworld
, С помощью board.replace_with(\n)
вызывает ошибку
File "<ipython-input-27-cdfade950fdf>", line 10
br.replace_with(\n)
^
SyntaxError: unexpected character after line continuation character
Другая информация: я использую Блокнот Jupyter, если это имеет какое-либо отношение. Вот моя полная программа, так как в другом месте я мог не заметить некоторые проблемы.
import requests
from bs4 import BeautifulSoup
import pandas as pd
page = requests.get("https://boards.4chan.org/g/")
soup = BeautifulSoup(page.content, 'html.parser')
board = soup.find('div', class_='board')
for br in board.select('br'):
br.replace_with('\n')
message = [obj.get_text() for obj in board.select('.opContainer .postMessage')]
image = [obj['href'] for obj in board.select('.opContainer .fileThumb')]
pid = [obj.get_text() for obj in board.select('.opContainer .postInfo .postNum a[title="Reply to this post"]')]
time = [obj.get_text() for obj in board.select('.opContainer .postInfo .dateTime')]
for x in range(len(image)):
image[x] = "https:" + image[x]
post = pd.DataFrame({
"ID": pid,
"Time": time,
"Image": image,
"Message": message,
})
post
pd.options.display.max_rows
pd.set_option('display.max_colwidth', -1)
display(post)
Любой совет будет принят во внимание. Спасибо за чтение.
4 ответа
Просто попробовал, и у меня это работает, моя версия bs4 - 4.8.0, и я использую Python 3.5.3, например:
from bs4 import BeautifulSoup
soup = BeautifulSoup('hello<br>world')
for br in soup('br'):
br.replace_with('\n')
# <br> was replaced with \n successfully
assert str(soup) == '<html><body><p>hello\nworld</p></body></html>'
# get_text() also works as expected
assert soup.get_text() == 'hello\nworld'
# it is a \n not a \\n
assert soup.get_text() != 'hello\\nworld'
Я не привык работать с Jupyter Notebook, но, похоже, ваша проблема в том, что все, что вы используете для визуализации данных, показывает вам строковое представление вместо фактической печати строки, надеюсь, это поможет, С уважением, adb
Вместо замены после преобразования в суп, попробуйте заменить <br>
теги перед преобразованием. Подобно,
soup = BeautifulSoup(str(page.content).replace('<br>', '\n'), 'html.parser')
Надеюсь это поможет! Ура!
PS: я не получил никакой логической причины, почему это не работает после превращения в суп.
После экспериментов с вариациями
page = requests.get("https://boards.4chan.org/g/")
str_page = page.content.decode()
str_split = '\n<'.join(str_page.split('<'))
str_split = '>\n'.join(str_split.split('>'))
str_split = str_split.replace('\n', '')
str_split = str_split.replace('<br>', ' ')
soup = BeautifulSoup(str_split.encode(), 'html.parser')
в течение большей части двух часов я определил, что фрейм данных Panda печатает символ новой строки как строковый литерал. Все остальное указывает на то, что программа работает так, как задумано, поэтому я предполагаю, что это было проблемой с самого начала.
по какой-то причине прямая замена с новой строкой не работает с bs4, вы должны сначала заменить какой-либо другой уникальный символ (предпочтительно последовательность символов), а затем заменить эту последовательность в тексте на новую строку.
попробуй это.
for br in soup.find_all('br'): br.replace_with('+++')
text=soup.get_text().replace('+++','\n)