python - BeautifulSoup 如何获取包含特定文本的父元素标签?尝试抓取电子邮件但无法获取父元素标签
问题描述
我正在尝试从页面中抓取电子邮件地址,但在获取包含电子邮件“@”符号的父元素时遇到了一些麻烦。电子邮件嵌入在不同的元素标签中,因此我无法将它们挑选出来。我必须浏览大约 50,000 页左右。
url = 'https://sec.report/Document/0001078782-20-000134/#f10k123119_ex10z22.htm'
以下是一些示例(一对来自我必须抓取的不同页面):
<div style="border-bottom:1px solid #000000">**dbrenner@umich.edu**</div>
<div class="f3c-8"><u**>Bob@LifeSciAdvisors.com**</u></div>
<p style="margin-bottom:0pt;margin-top:0pt;;text-indent:0pt;;font-family:Arial;font-size:11pt;font-weight:normal;font-style:normal;text-transform:none;font-variant: normal;">Email: **dmoskowitz@biocept.com**; Phone: 858-320-8244</p>
<td class="f8c-43">E-mail: <u>jcohen@2020gene.com</u></td>
<p class="f7c-4">Email: jcohen@2020gene.com</p>
我试过的:
- 我尝试 find_all('div') 来获取所有 div 的 ResultSet 以获取其中包含“@”符号的那些。
div = page.find_all('div')
for each in div:
if '@' in each.text:
print(each.text)
当我这样做时,由于正文位于“div”中,它打印了整个页面。失败。由于电子邮件嵌入在不同的标签中,这种方法似乎效率低下
- 使用正则表达式。我尝试使用正则表达式来挑选电子邮件,但它会得到一堆不可用的文本,我必须手动拆分、替换字符等。这似乎是一项艰巨的任务,要经历所有不同的场景。
import re
emails = re.findall('\S+@\S+', str(page))
for each in emails:
print(each)
这样做给了我这样的东西:
hidden;}@media
#000000">dbrenner@umich.edu</div>
#000000">kherman@umich.edu
#000000">spage@fredhutch.org</div>
#000000">mtuck@umich.edu</div>
#000000">jdahlgre@fredhutch.org</div></p>
#000000">lafky.jacqueline@mayo.edu</div></p>
mtuck@umich.edu)</div>
#000000">ctsucontact@westat.com</div>.
href="http://@umich.edu">@umich.edu</a></li><li><a
现在我可以使用 .split('<') 进入并拆分一些文本,然后再次拆分,等等。但它们并不完全相同,因为我必须在每页中抓取 50,000 多页,每页有 100 个条目,所以有很多我不得不刮和考虑。
我尝试在 google 和 stackoverflow 上查找,但我能找到的只是人们在某个元素中寻找文本的解决方案,等等。
我需要的是“如何找到包含电子邮件的父元素”
我认为我不需要为此使用 Selenium,因为该问题类似于使用 Beautifulsoup,并且该站点不是 JavaScript 呈现的,除了某些页面是 pdf 之外,这完全是另一个问题。
任何见解,帮助或建议表示赞赏。谢谢。
解决方案
有两个选项可以搜索包含@
符号的文本:
使用 CSS 选择器
:contains(<MY TEXT>)
搜索其中包含@
符号的文本。在方法中使用
lambda
函数find_all()
,并搜索是否@
在.text()
.soup
选项1:
from bs4 import BeautifulSoup
html = """<div style="border-bottom:1px solid #000000">**dbrenner@umich.edu**</div>
<div class="f3c-8"><u**>Bob@LifeSciAdvisors.com**</u></div>
<p style="margin-bottom:0pt;margin-top:0pt;;text-indent:0pt;;font-family:Arial;font-size:11pt;font-weight:normal;font-style:normal;text-transform:none;font-variant: normal;">Email: **dmoskowitz@biocept.com**; Phone: 858-320-8244</p>
<td class="f8c-43">E-mail: <u>jcohen@2020gene.com</u></td>
<p class="f7c-4">Email: jcohen@2020gene.com</p>"""
soup = BeautifulSoup(html, "html.parser")
for tag in soup.select('*:contains("@")'):
print(tag.text.strip())
选项 2:
for tag in soup.find_all(lambda t: "@" in t.text.strip()):
print(tag.text.strip())
推荐阅读
- python - 调用使用 argparse 的函数
- python - 如何只删除一次出现的键?
- python - 即使在单击下一步按钮后,脚本也会从第一页获取相同的结果
- android - 如何在Android中模拟按钮按下
- python - 在python中的字符串mongo查询中传递参数
- java - 在Android中控制音乐播放器的音乐
- c++ - 当有多个匹配可能性时,`std::regex_search` 是否有任何保证
- react-native - 将道具传递给 tabNavigator 的屏幕
- python - 试图从雅虎股票数据中打印第一个高值,得到“基于非整数索引的索引只能有非整数索引器”
- r - 用 ggplot 绘制不相似的数据