嘗試抓取部分目錄 (toc),最好使用 SoupSieve:
<html>
<dl>
#many rows
<dd>4.2.1. Drivers</dd>
<dd>4.2.1.1. itemD1</dd>
<dd>4.2.1.2. itemD2</dd>
<dd>4.2.1.3. itemD3</dd>
<dd>4.2.2. Constraints</dd>
<dd>4.2.2.1. itemC1</dd>
#many more rows
</dl>
</html>
請注意,我需要的物品不是 4.2.1 的孩子/后代。驅動程式,只是因為編號看起來像。
現在,我需要抓取的元素是元素 Drivers 和 Constraints 之間的元素。并不總是 3 個——它可能是 0、3 或 5 個,取決于。稍后在我的代碼中,我使用 Pandas 將這些元素輸出到 .csv 中的單個單元格中。
我試過這樣的事情:
def get_drivers():
data.append({
'url': url,
'type': 'driver',
'list': [x.get_text(strip=True) for x in toc.select('dd:-soup-contains-own("Drivers") ~ dd')]
})
...但這只是給了我從驅動程式到檔案末尾的所有元素,通常是我不需要的幾十個元素。
問題:如何讓選擇器在 Drivers 之后開始選擇并在 Constraints 停止選擇?
uj5u.com熱心網友回復:
您絕對可以使用 css 選擇器來做到這一點。使用:-soup-contains和:not,與一般的兄弟組合子(一起~)和型別選擇(dd),以篩選出每個之后的部分(即減去 Constraints從開始 Drivers起
from bs4 import BeautifulSoup as bs
html = '''<html>
<dl>
#many rows
<dd>4.2.1. Drivers</dd>
<dd>4.2.1.1. itemD1</dd>
<dd>4.2.1.2. itemD2</dd>
<dd>4.2.1.3. itemD3</dd>
<dd>4.2.2. Constraints</dd>
<dd>4.2.2.1. itemC1</dd>
#many more rows
</dl>
</html>'''
soup = bs(html, 'lxml')
filtered = [i.text for i in soup.select(
'dd:-soup-contains(" Drivers") ~ dd:not(dd:-soup-contains(" Constraints"), dd:-soup-contains(" Constraints") ~ dd)')]
我想回圈可能也能作業,盡管 IMO 不太可取:
from bs4 import BeautifulSoup as bs
html = '''<html>
<dl>
#many rows
<dd>4.2.1. Drivers</dd>
<dd>4.2.1.1. itemD1</dd>
<dd>4.2.1.2. itemD2</dd>
<dd>4.2.1.3. itemD3</dd>
<dd>4.2.2. Constraints</dd>
<dd>4.2.2.1. itemC1</dd>
#many more rows
</dl>
<dl>
<dd>Error</dd>
</dl>
</html>'''
soup = bs(html, 'lxml')
start = soup.select_one('dd:-soup-contains(" Drivers") dd')
next_node = start
while True:
if not next_node:
break
if 'Constraints' in next_node.text:
break
print(next_node.text)
next_node = next_node.find_next('dd')
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/370721.html
