【问题标题】:Python HTML getting div ID by textPython HTML通过文本获取div ID
【发布时间】:2019-03-12 15:11:00
【问题描述】:

我有一个不寻常的要求;我想根据它在网页上显示的文本获取 div 的 id。例如,假设我有以下 html:

<div class="productTabRightCompatibility">
 <h2>
  Product Downloads
 </h2>
 <ul class="listColumn">
  <li>
   <div class="iconSprite icon16 iconDownloads" id="layoutmain_1_ProductTabs1_rptResources_divResourceImage_0">
   </div>
   <a href="/-/dummy_link_one_technical_drawing" id="layoutmain_1_ProductTabs1_rptResources_hlResourceLink_0" target="_blank">
    ProductOne Technical Drawing
   </a>
  </li>
  <li>
   <div class="iconSprite icon16 iconDownloads" id="layoutmain_1_ProductTabs1_rptResources_divResourceImage_1">
   </div>
   <a href="/-/dummy_link_two_cad_drawing" id="layoutmain_1_ProductTabs1_rptResources_hlResourceLink_1" target="_blank">
    ProductOne CAD Drawing
   </a>
  </li>
  <li>
   <div class="iconSprite icon16 iconDownloads" id="layoutmain_1_ProductTabs1_rptResources_divResourceImage_2">
   </div>
   <a href="/-/dummy_link_three_installation_manual" id="layoutmain_1_ProductTabs1_rptResources_hlResourceLink_2" target="_blank">
    ProductOne Installation Manual
   </a>
  </li>
 </ul>
</div>

不幸的是,网站并不总是以相同的顺序排列这些,所以有时技术图纸由 id ResourceLink_0 表示,有时 CAD 图纸是。唯一不变的是我想要的项目用文本“[Product #] Technical Drawing”表示。我希望能够浏览多个页面并获得与技术图纸相对应的链接,而不管顺序如何。目前我正在遍历所有链接,并在链接地址中的某处寻找包含“technical_drawing”的链接,但我想知道是否有更好的方法来获得结果。

【问题讨论】:

  • 您希望如何改进您之前的解决方案?它似乎做你想做的事。
  • @Mr.Yellow 我只是想知道是否有一种方法可以根据页面上显示的文本找到链接,而不是遍历所有链接。如果我这样做的方式是最有效的方式,那很好,只是试图确保我尽可能保持 Python 风格。

标签: python python-3.x web-scraping beautifulsoup


【解决方案1】:

使用BeautifulSoup 和re 包,您应该可以执行以下操作:

from bs4 import BeautifulSoup
import re

html = """<div class="productTabRightCompatibility">
 <h2>
  Product Downloads
 </h2>
 <ul class="listColumn">
  <li>
   <div class="iconSprite icon16 iconDownloads" id="layoutmain_1_ProductTabs1_rptResources_divResourceImage_0">
   </div>
   <a href="/-/dummy_link_one_technical_drawing" id="layoutmain_1_ProductTabs1_rptResources_hlResourceLink_0" target="_blank">
    ProductOne Technical Drawing
   </a>
  </li>
  <li>
   <div class="iconSprite icon16 iconDownloads" id="layoutmain_1_ProductTabs1_rptResources_divResourceImage_1">
   </div>
   <a href="/-/dummy_link_two_cad_drawing" id="layoutmain_1_ProductTabs1_rptResources_hlResourceLink_1" target="_blank">ProductOne CAD Drawing</a>
  </li>
  <li>
   <div class="iconSprite icon16 iconDownloads" id="layoutmain_1_ProductTabs1_rptResources_divResourceImage_2">
   </div>
   <a href="/-/dummy_link_three_installation_manual" id="layoutmain_1_ProductTabs1_rptResources_hlResourceLink_2" target="_blank">
    ProductOne Installation Manual
   </a>
  </li>
 </ul>
</div>"""
soup = BeautifulSoup(html,'html.parser')
a_link = soup.find('a', text=re.compile("ProductOne Technical Drawing"))
print(a_link.get('href'))

输出:

/-/dummy_link_one_technical_drawing

【讨论】:

  • 你为什么复制我的答案?
  • 1.请注意,我的编辑是在您回答 2 之前一分钟写的。请确保在“复制 SO 答案”之前我有很多事情要做,不客气
  • 我看到了你之前发布的内容。好吧。不要太聪明了。
【解决方案2】:

使用re 可以搜索标签的文本,然后获取该标签的href 值。 如果页面上存在多个元素,我在这里使用了find_all。

import bs4
import re
html_doc='''<html><div class="productTabRightCompatibility">
 <h2>
  Product Downloads
 </h2>
 <ul class="listColumn">
  <li>
   <div class="iconSprite icon16 iconDownloads" id="layoutmain_1_ProductTabs1_rptResources_divResourceImage_0">
   </div>
   <a href="/-/dummy_link_one_technical_drawing" id="layoutmain_1_ProductTabs1_rptResources_hlResourceLink_0" target="_blank">
    ProductOne Technical Drawing
   </a>
  </li>
  <li>
   <div class="iconSprite icon16 iconDownloads" id="layoutmain_1_ProductTabs1_rptResources_divResourceImage_1">
   </div>
   <a href="/-/dummy_link_two_cad_drawing" id="layoutmain_1_ProductTabs1_rptResources_hlResourceLink_1" target="_blank">
    ProductOne CAD Drawing
   </a>
  </li>
  <li>
   <div class="iconSprite icon16 iconDownloads" id="layoutmain_1_ProductTabs1_rptResources_divResourceImage_2">
   </div>
   <a href="/-/dummy_link_three_installation_manual" id="layoutmain_1_ProductTabs1_rptResources_hlResourceLink_2" target="_blank">
    ProductOne Installation Manual
   </a>
  </li>
 </ul>
</div></html>'''

soup =bs4.BeautifulSoup(html_doc, 'html.parser')
items=soup.find_all('a' , text=re.compile("Technical Drawing"))
for item in items:
  print(item['href'])

输出:

/-/dummy_link_one_technical_drawing

【讨论】:

  • 正确答案,刚刚得到 Maaz 的第一个。
【解决方案3】:

您可以避免使用 find 和 regex 并使用更快的 css 属性 = 值选择器并以 $ 运算符结尾

[href$='technical_drawing']

代码:

from bs4 import BeautifulSoup as bs

html='''<html><div class="productTabRightCompatibility">
 <h2>
  Product Downloads
 </h2>
 <ul class="listColumn">
  <li>
   <div class="iconSprite icon16 iconDownloads" id="layoutmain_1_ProductTabs1_rptResources_divResourceImage_0">
   </div>
   <a href="/-/dummy_link_one_technical_drawing" id="layoutmain_1_ProductTabs1_rptResources_hlResourceLink_0" target="_blank">
    ProductOne Technical Drawing
   </a>
  </li>
  <li>
   <div class="iconSprite icon16 iconDownloads" id="layoutmain_1_ProductTabs1_rptResources_divResourceImage_1">
   </div>
   <a href="/-/dummy_link_two_cad_drawing" id="layoutmain_1_ProductTabs1_rptResources_hlResourceLink_1" target="_blank">
    ProductOne CAD Drawing
   </a>
  </li>
  <li>
   <div class="iconSprite icon16 iconDownloads" id="layoutmain_1_ProductTabs1_rptResources_divResourceImage_2">
   </div>
   <a href="/-/dummy_link_three_installation_manual" id="layoutmain_1_ProductTabs1_rptResources_hlResourceLink_2" target="_blank">
    ProductOne Installation Manual
   </a>
  </li>
 </ul>
</div></html>'''

soup =bs(html, 'lxml')
link =soup.select_one("[href$='technical_drawing']")['href']
print(link)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-09
    • 1970-01-01
    • 2013-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-18
    相关资源
    最近更新 更多