Python BeautifulSoup Автоматическое отслеживание строк и столбцов таблицы содержимого

87
8

Сначала позвольте мне сказать, что я новичок в Stack и Python. Я только начал работать с ним на прошлой неделе. Я, тем не менее, опытный программист PHP/С++/Pascal/ADA/B/Forth (показывающий моего возраста).


Я написал script, который выводит страницы продукта с веб-сайта и сохраняет их в моей локальной базе данных MySQL. Я сделал это, чтобы я мог ползти по сайту поздно ночью, когда нагрузка светлая. Теперь мне нужно отсортировать html каждой страницы и получить описания продуктов. Они помещаются в таблицы. Однако каждая страница может иметь необходимые значения в разных строках/столбцах.


Я могу быть уверен в том, что:


    Каждая таблица имеет заголовок, который определяет данные в строках/столбцах ниже.
    Текст заголовка согласован для каждого значения, т.е. "Часть" всегда описывает тип детали и "Номер детали" всегда описывает номер детали.
    Не все страницы будут содержать все необходимые данные. Поэтому, если он не находится, он должен сохранить то, что он находит.

В следующем разделе это вторая часть, получающая значения данных, с которыми у меня возникают проблемы. Как выбрать n-й столбец из строки?



Мой текущий подход:


Получить желаемые столбцы


    Получить html doc из db
    Возьмите таблицу (моя таблица всегда содержится в единственном div на странице.
    Захватите все строки (на самом деле нужно только сделать это для первой строки)
    Для каждой строки захватывать индекс строки и столбца ', когда я нахожу нужные имена полей.

Получить значения данных


    Для каждой строки:
    Пропустить строку, если она была заголовком (сохранить количество строк для полей заголовков)
    для каждого столбца возьмите текстовое значение.
    Сохранить значения в db

Важная часть моей страницы выглядит так:


<div>
...
<table>
<tr><td> </td><td><b>Item</b></td><td> </td><td><b>Description</b></td><td> </td><td><b>Part No.</b></td><td> </td><td><b>Color</b></td><td> </td></tr>
<tr><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
<tr><td> </td><td>Toaster</td><td> </td><td>2-Slice</td><td> </td><td>#25713</td><td> </td><td>Chorme</td><td> </td></tr>
</table>
...
</div>

Большое спасибо всем, кто отвечает.

спросил(а) 2021-01-19T16:45:23+03:00 2 месяца, 3 недели назад
1
Решение
107

Вот как я справился бы с этим:


from BeautifulSoup import BeautifulSoup

doc = '''<div>
<table>
<tr><td> </td><td><b>Item</b></td><td> </td><td><b>Description</b></td><td> </td><td><b>Part No.</b></td><td> </td><td><b>Color</b></td><td> </td></tr>
<tr><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
<tr><td> </td><td>Toaster</td><td> </td><td>2-Slice</td><td> </td><td>#25713</td><td> </td><td>Chorme</td><td> </td></tr>
</table>
</div>'''

soup = BeautifulSoup(doc)
# find the table element in the HTML document
table = soup.find("table")
# grabs the top row
firstRow = table.contents[0]
# find how many columns there are
numberOfColumns = len(firstRow.contents)
restOfRows = table.contents[1:]
for row in restOfRows:
for x in range(0,numberOfColumns):
print "column data: %s" % row.contents[x].string

Это извлечет элемент таблицы из любого документа. Затем найдите количество столбцов на основе первой строки. Наконец, он будет проходить через остальные строки, распечатывая данные в строке.


Полезная ссылка на документы BS: http://www.crummy.com/software/BeautifulSoup/documentation.html

ответил(а) 2021-01-19T16:45:23+03:00 2 месяца, 3 недели назад
43

Вот как вы это делаете с HTQL:

import htql;
doc = '''<div> <table>
<tr><td> </td><td><b>Item</b></td><td> </td><td><b>Description</b></td><td>  </td><td><b>Part No.</b></td><td> </td><td><b>Color</b></td><td> </td></tr>
<tr><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
<tr><td> </td><td>Toaster</td><td> </td><td>2-Slice</td><td> </td><td>#25713</td><td> </td><td>Chorme</td><td> </td></tr>
</table> </div>''';

query = "<div>.<table>.<tr>{item=<td (th='Item')>&tx; desc=<td (th='Description')>&tx | item<>'Item'}";

for item, desc in htql.HTQL(doc, query):
print(item, desc);

ответил(а) 2021-01-19T16:45:23+03:00 2 месяца, 3 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема