我在根据文字找到汤中的值时遇到问题。这是代码
from bs4 import BeautifulSoup as bs
import requests
import re
html='http://finance.yahoo.com/q/ks?s=aapl+Key+Statistics'
r = requests.get(html)
soup = bs(r.text)
findit=soup.find("td", text=re.compile('Market Cap'))
这会返回[],但“td”中绝对有文字。标记为' Market Cap'。 当我使用
soup.find_all("td")
我得到的结果集包括:
<td class="yfnc_tablehead1" width="74%">Market Cap (intraday)<font size="-1"><sup>5</sup></font>:</td>
答案 0 :(得分:2)
<强>解释强>
问题是这个特定的标签有其他子元素,.string
值在应用文本参数时被检查,是None
(bs4记录了here) 。
<强>解决方案/解决方法:强>
此处不要指定标记名称,找到文本节点并转到父级:
soup.find(text=re.compile('Market Cap')).parent.get_text()
或者,如果td
不是文本节点的直接父级,则可以使用find_parent()
:
soup.find(text=re.compile('Market Cap')).find_parent("td").get_text()
您还可以使用"search function"搜索td
标记,并查看直接文本子节点是否包含Market Cap
文本:
soup.find(lambda tag: tag and
tag.name == "td" and
tag.find(text=re.compile('Market Cap'), recursive=False))
或者,如果您希望找到以下号码5
:
soup.find(text=re.compile('Market Cap')).next_sibling.get_text()
答案 1 :(得分:2)
您无法在标记中使用正则表达式。它不会起作用。不知道这是否是规范的错误。我只是搜索,然后让父母回到列表理解中,因为“td”“regex”会给你td标签。
<强>代码强>
from bs4 import BeautifulSoup as bs
import requests
import re
html='http://finance.yahoo.com/q/ks?s=aapl+Key+Statistics'
r = requests.get(html)
soup = bs(r.text, "lxml")
findit=soup.find_all(text=re.compile('Market Cap'))
findit=[x.parent for x in findit if x.parent.name == "td"]
print(findit)
<强>输出强>
[<td class="yfnc_tablehead1" width="74%">Market Cap (intraday)<font size="-1"><sup>5</sup></font>:</td>]
答案 2 :(得分:0)
正则表达式是整合到解析代码中的一个可怕的事情,我认为应尽可能避免使用。
就个人而言,由于缺乏XPath支持,我不喜欢BeautifulSoup。你想要做的是XPath非常适合的那种东西。如果我正在做你正在做的事情,我会使用lxml进行解析,而不是使用BeautifulSoup内置的解析和/或正则表达式。它真的很优雅,非常快:
from lxml import etree
import requests
source = requests.get('http://finance.yahoo.com/q/ks?s=aapl+Key+Statistics').content
parsed = etree.HTML(source)
tds_w_market_cap = parsed.xpath('//td[contains(., "Market Cap")]')
上述FYI返回一个lxml对象而不是页面源文本。在lxml中,你本身并不直接使用源代码。如果由于某种原因需要返回实际源列表,可以添加如下内容:
print [etree.tostring(i) for i in tds_w_market_cap]
如果您必须使用BeautifulSoup完成此任务,那么我将使用列表理解:
from bs4 import BeautifulSoup as bs
import requests
source = requests.get('http://finance.yahoo.com/q/ks?s=aapl+Key+Statistics').content
parsed = bs(source, 'lxml')
tds_w_market_cap = [i for i in parsed.find_all('td') if 'Market Cap' in i.get_text()]