#python #css #beautifulsoup
#python #css #beautifulsoup
Вопрос:
Спасибо, если вы обратили внимание на мой пост,
После многих исследований я не смог найти среднее значение для очистки строки таблицы только в том случае, если ячейка содержит определенное значение.
Более конкретно: я хочу сохранить строку, содержащую слово «oui», в последнем столбце следующей таблицы:
<table align="center" cellspacing="0" cellpadding="3" width="100%">
<tbody><tr>
<td class="tdhg" align="left"><b>Liste des candidats</b></td>
<td class="tdhv"><strong>Voix</strong></td>
<td class="tdhv"><strong>%amp;nbsp;Inscrits</strong></td>
<td class="tdhv"><strong>%amp;nbsp;Exprimés</strong></td>
<td class="tdhv"><strong>Elu(e)</strong></td>
</tr>
<tr>
<td class="tdcbf" align="left">M.amp;nbsp;Jean-François LAMOURamp;nbsp;(UMP) </td>
<td class="tdcd" align="right">23amp;nbsp;964</td>
<td class="tdcd" align="right"> 33,01</td>
<td class="tdcd" align="right"> 54,60</td>
<td class="tdcd" align="center">oui
amp;nbsp;</td>
</tr>
<tr>
<td class="tdcbf" align="left">M.amp;nbsp;Gilles ALAYRACamp;nbsp;(RDG) </td>
<td class="tdcd" align="right">19amp;nbsp;927</td>
<td class="tdcd" align="right"> 27,45</td>
<td class="tdcd" align="right"> 45,40</td>
<td class="tdcd" align="center">
amp;nbsp;</td>
</tr>
</tbody></table>
Сначала я попытался выполнить регулярное выражение, я успешно нашел подходящее слово, но сохранить соответствующую строку кажется сложным, поэтому я решил изменить метод и пройти BeautifulSoup.
Лучшее, что я сделал на данный момент, это:
url='www.someurl.com'
headers = {"User-Agent":"Mozilla/5.0"}
response = requests.get(url.format())
html_soup = soup(response.content, 'lxml')
html_soup.select('td.tdcd')
Я не могу пойти дальше, в частности, заявив, что нужно сохранить ‘tr’ там, где ‘tdcd’ содержит ‘oui’. Даже если я прочитал документацию https://www.crummy.com/software/BeautifulSoup/bs4/doc /, довольно сложно рассматривать значение ячейки как дочерней, если я не ошибаюсь.
Спасибо,
Ответ №1:
найдите td.tdcd
то, что содержит oui
, выберите его родительским
html_soup = soup(response.content, 'lxml')
tds = html_soup.select('td.tdcd')
for td in tds :
if 'oui' in td.text:
print(td.parent)
Комментарии:
1. Большое вам спасибо, это определенно то, что я искал! Я сосредоточился на детях, а не на родителях, это довольно интересный подход. И последний маленький вопрос: почему только td.parent отображает строку без «oui» внутри (это просто для полного понимания механики)?
2. это отображение
oui
, на котором вы можете его протестировать repl.it/@uingtea/PythonTester
Ответ №2:
Это то, что вам нужно? Просто считайте в фрейм данных, а затем фильтруйте фрейм данных
html = '''<table align="center" cellspacing="0" cellpadding="3" width="100%">
<tbody><tr>
<td class="tdhg" align="left"><b>Liste des candidats</b></td>
<td class="tdhv"><strong>Voix</strong></td>
<td class="tdhv"><strong>%amp;nbsp;Inscrits</strong></td>
<td class="tdhv"><strong>%amp;nbsp;Exprimés</strong></td>
<td class="tdhv"><strong>Elu(e)</strong></td>
</tr>
<tr>
<td class="tdcbf" align="left">M.amp;nbsp;Jean-François LAMOURamp;nbsp;(UMP) </td>
<td class="tdcd" align="right">23amp;nbsp;964</td>
<td class="tdcd" align="right"> 33,01</td>
<td class="tdcd" align="right"> 54,60</td>
<td class="tdcd" align="center">oui
amp;nbsp;</td>
</tr>
<tr>
<td class="tdcbf" align="left">M.amp;nbsp;Gilles ALAYRACamp;nbsp;(RDG) </td>
<td class="tdcd" align="right">19amp;nbsp;927</td>
<td class="tdcd" align="right"> 27,45</td>
<td class="tdcd" align="right"> 45,40</td>
<td class="tdcd" align="center">
amp;nbsp;</td>
</tr>
</tbody></table>'''
import pandas as pd
table = pd.read_html(html)[0]
# Keep any rows that have 'oui' in the row; doesn't matter which column
filter_table = table[table.values == 'oui']
# Or if you specifically need to look in the last column
#filter_table = table[table.iloc[:,-1] == 'oui']
# Or specific column name
#filter_table = table[table[4] == 'oui']
Вывод:
print (filter_table)
0 1 2 3 4
1 M. Jean-François LAMOUR (UMP) 23 964 3301 5460 oui
Альтернативный вариант:
Здесь вы можете перебирать строки и добавлять только в том случае, если они содержат 'oui'
html_soup = BeautifulSoup(html, 'lxml')
data_rows = html_soup.select('tr')
rows = []
for row in data_rows:
data = [ x.text.strip() for x in row.find_all('td',{'class':'tdcd'})]
if 'oui' in data:
rows.append(data)
table = pd.DataFrame(rows)
Комментарии:
1. Спасибо за этот ответ, который кажется вполне последовательным. Ну, я не думал о фильтрации на этапе panda, но это может помочь. Проблема в том, что я удаляю кучу переменных на одних и тех же страницах, чтобы они повторялись на каждой странице для каждой строки (даже если она не содержит ‘oui’) и потому, что у меня много страниц, которые я хотел отфильтровать перед сохранением в файл panda.
2. ах, хорошо. Я тоже буду работать над альтернативным решением. Но Я. Это имеет смысл
3. Большое вам спасибо!