为什么我不能使用BeautifoulSoup向下钻取到我想要的标签
我想从CME(芝加哥商品交易所(中提取产品代码。
Q1:我想我可以从表中提取它 -> tr。但代码只停留在交易时间的文本上。请指导我如何更深入地获取带有某些文本的产品代码。
如果成功了,我们应该能够看到:
芝商所环球:ZC
芝商所明港:C
清算:C
TAS: ZCT
Q2:然后不知何故,我只需要ZC这个词,然后放在我的csv文件中。
from urllib.request import urlopen as uReq
from urllib.request import Request
from bs4 import BeautifulSoup as soup
AccessCME=Request("http://www.cmegroup.com/trading/agricultural/grain-and-
oilseed/corn_contract_specifications.html",headers={"User-Agent":"Mozilla/5.0"})
CMEPage=uReq(AccessCME).read()
page_soup=soup(CMEPage,"html.parser")
table=page_soup.find("table")
rows=table.find_all("tr")
print(rows)
如果不清楚,请告诉我,然后我会澄清更多。
我不知道为什么你会得到表格的那一行。但是,我可以说,在确定实际想要的行时,您需要更加小心。我注意到只有一个标有包含"产品"一词的术语。我决定寻找那个。我还使用了requests
模块,因为它的问题往往较少。
首先,我找到所有可能成为我想要的td
元素。然后,我确定其中text
属性中包含"产品"的那个。我称它为parent_td
,当它真的应该,比如说,sibling_td
.我验证它是否包含我希望的内容。
现在,我在它的兄弟姐妹中寻找其他td
元素,获取其text
属性并在两端去除空白。我将结果显示为target
.
最后,我使用两个re.sub
调用,一个在另一个中丢弃我不想要的字符串片段,产生你想要的。
这一切都异常尴尬。
>>> import requests
>>> page = requests.get('http://www.cmegroup.com/trading/agricultural/grain-and-oilseed/corn_contract_specifications.html').content
>>> import bs4
>>> soup = bs4.BeautifulSoup(page, 'lxml')
>>> possible_tds = soup.find_all('td', attrs={'class':"prodSpecAtribute"})
>>> parent_td = [td for td in possible_tds if 'Product' in td.text][0]
>>> parent_td
<td class="prodSpecAtribute">Product Code</td>
>>> target = parent_td.fetchNextSiblings('td')[0].text.strip()
>>> target
'CME Globex: ZCCME ClearPort: CClearing: CTAS: ZCT'
>>> import re
>>> re.sub(r'CME Globex:s+', '', target)
'ZCCME ClearPort: CClearing: CTAS: ZCT'
>>> re.sub(r'CME ClearPort:.*', '', re.sub(r'CME Globex:s+', '', target))
'ZC'
编辑(回复评论(:
Q1:根据我的经验,我几乎总是使用lxml
,因为它总是有效。如果我碰巧注意到这个问题涉及使用其他东西,我会使用其他东西,这似乎很重要。
Q2:[td for td in possible_tds if 'Product' in td.text]
就是所谓的列表理解。它有一个表达式,在这种情况下只是一个变量td
,一个for循环,在这种情况下,for td in possible_tds
,以及可选的条件,在这种情况下,if 'Product' in td.text
。列表推导式列出了其中由条件控制的 for 循环给出的表达式。
possible_tds
来自之前的声明。它是soup
中具有特定class
的td
元素的列表。列表推导式中的 for 循环会浏览这些内容,查找其text
属性包含"产品"的那些。那些这样做的人将添加到成为parent_td
的列表中。我们知道只有一个;因此,我们要求列表中的[0]
项。