Как извлечь все элементы из таблиц с помощью BeautifulSoup? - PullRequest
2 голосов
/ 09 марта 2020

У меня есть большой HTML файл, который был создан с объединением нескольких HTML файлов, поэтому структура повторяется N раз <html>..</html> <html>..</html>, например:

<html>
<head>
<body>
    <TABLE>
    <TABLE>  
</body>
</html>

<html>
<head>
<body>
    <TABLE>
    <TABLE>  
</body>
</html>

<html>
<head>
<body>
    <TABLE>
    <TABLE>  
</body>
</html> 

Более полный пример приведен здесь https://jsfiddle.net/28du1omt/

Я хотел бы извлечь все виды элементов из второй таблицы каждого html block, чтобы получить это:

Я говорю все элементы, так как вторая таблица может иметь внутренние абзацы, таблицы, изображения, ссылки http и т. д. c (<p>, <img>, <tables>, etc)

<html>
  <head>
  </head>
  <body> 
        <p>&nbsp;</p>
        <p><font size="5" color="red">some text file 1</font></p>   
        <p><font size="4" color="purple">some text file 1</font></p>  
        <p>&nbsp;</p>
        <p>some text file 2</p>
        <p>&nbsp;</p>
        <p>some text file 3</p>                 
  </body>
</html>

Как я могу это сделать?

My текущий код просматривает все элементы таблицы в файле, но я не знаю, как извлечь только элементы из каждой второй таблицы каждого блока html.

from bs4 import BeautifulSoup

fp = open("file.html", "rb")
soup = BeautifulSoup(fp, "html5lib")

tables = soup.find_all('table')

for tbl in tables:
    print(tbl.find_all())

Ответы [ 3 ]

1 голос
/ 09 марта 2020

Мой текущий код просматривает все элементы таблиц в файле, но я не знаю, как извлечь только элементы внутри каждой второй таблицы каждого блока html.

Вы находитесь на правильный путь уже. Как насчет итерации сначала по html блокам, а затем только по выбору появления вторых таблиц? Должно быть достаточно, нет?

raw_html = """<html>
<head>
<body>
    <table></table>
    <table><test id="second_table">test text 1</test></table>
</body>
</html>
<html>
<head>
<body>
    <table></table>
    <table><test id="second_table">test text 2</test></table>
</body>
</html>
<html>
<head>
<body>
    <table></table>
    <table><test id="second_table">test text 3</test></table>
</body>
</html>"""

soup = BeautifulSoup(raw_html, "html.parser")

for html_block in soup.find_all("html"):
    interesting_table = html_block.find_all("table")[1]  # keep the second table only
    print(interesting_table)  # do what you want with these tables now

Вывод:

<table><test id="second_table">test text 1</test></table>
<table><test id="second_table">test text 2</test></table>
<table><test id="second_table">test text 3</test></table>
0 голосов
/ 09 марта 2020

Рекомендовать библиотеку, которая обрабатывает все теги HTML как строки.

from simplified_scrapy import SimplifiedDoc
html = '''
<html>
<head>
<body>
    <table></table>
    <table><test id="test_id">test text 1</test></table>
</body>
</html>
<html>
<head>
<body>
    <table></table>
    <table><test id="test_id">test text 2</test></table>
</body>
</html>
<html>
<head>
<body>
    <table></table>
    <table><test id="test_id">test text 3</test></table>
</body>
</html> 
'''
doc = SimplifiedDoc(html)
htmls = doc.htmls
for h in htmls:
  table = h.getElement('table',start='</table>') # Use start='</table>' to skip the first table
  print (table.test.text)
  print (table.select('test#test_id'))

Результат:

test text 1
{'id': 'test_id', 'tag': 'test', 'html': 'test text 1'}
test text 2
{'id': 'test_id', 'tag': 'test', 'html': 'test text 2'}
test text 3
{'id': 'test_id', 'tag': 'test', 'html': 'test text 3'}
0 голосов
/ 09 марта 2020

Если вы хотите html таблицу в фрейм данных, вы можете попробовать эту

import pandas as pd
import html5lib
url = 'file.html'
dfs = pd.read_html(url)
df = pd.concat(dfs)
df

вы можете go до read_ html документацию, так как вы можете предоставить идентификаторы таблицы чтобы получить конкретную html таблицу и c как attrs = {'id': 'table'}

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