Jam*_*len 3 python parsing lxml
我试图实现一个lxml, xpath
代码来解析链接中的 html:https://www.theice.com/productguide/ProductSpec.shtml?specId=251
具体来说,我试图解析<tr class="last">
页面末尾附近的表格。
我想获取该子表中的文本,例如:“纽约”及其旁边列出的时间(对伦敦和新加坡执行相同的操作)。
我有以下代码(无法正常工作):
doc = lxml.html.fromstring(page)
tds = doc.xpath('//table[@class="last"]//table[@id"tradingHours"]/tbody/tr/td/text()')
Run Code Online (Sandbox Code Playgroud)
与美丽汤:
table = soup.find('table', attrs={'id':'tradingHours'})
for td in table.findChildren('td'):
print td.text
Run Code Online (Sandbox Code Playgroud)
实现这一目标的最佳方法是什么?我想使用lxml
not beautifulSoup
(只是为了看看区别)。
您的lxml
代码非常接近工作。主要问题是table
标签不是具有class="last"
属性的标签。相反,它是一个tr
具有该属性的标签:
</tr><tr class="last"><td>TRADING HOURS</td>
Run Code Online (Sandbox Code Playgroud)
因此,
//table[@class="last"]
Run Code Online (Sandbox Code Playgroud)
没有匹配项。还有一个小语法错误:@id"tradingHours"
should be @id="tradingHours"
。
您也可以//table[@class="last"]
完全省略,因为table[@id="tradingHours"]
它足够具体。
与 BeautifulSoup 代码最接近的模拟是:
import urllib2
import lxml.html as LH
url = 'https://www.theice.com/productguide/ProductSpec.shtml?specId=251'
doc = LH.parse(urllib2.urlopen(url))
for td in doc.xpath('//table[@id="tradingHours"]//td/text()'):
print(td.strip())
Run Code Online (Sandbox Code Playgroud)
在解析表时,石斑鱼食谱zip(*[iterable]*n)
通常非常有用。它将项目收集到项目iterable
组中n
。我们可以在这里使用它,如下所示:
texts = iter(doc.xpath('//table[@id="tradingHours"]//td/text()'))
for group in zip(*[texts]*5):
row = [item.strip() for item in group]
print('\n'.join(row))
print('-'*80)
Run Code Online (Sandbox Code Playgroud)
我不太擅长解释石斑鱼食谱的工作原理,但我在这里做了一次尝试。
此页面使用 JavaScript 来重新格式化日期。要在JavaScript 更改内容后抓取页面,您可以使用selenium:
import urllib2
import lxml.html as LH
import contextlib
import selenium.webdriver as webdriver
url = 'https://www.theice.com/productguide/ProductSpec.shtml?specId=251'
with contextlib.closing(webdriver.PhantomJS('phantomjs')) as driver:
driver.get(url)
content = driver.page_source
doc = LH.fromstring(content)
texts = iter(doc.xpath('//table[@id="tradingHours"]//td/text()'))
for group in zip(*[texts]*5):
row = [item.strip() for item in group]
print('\n'.join(row))
print('-'*80)
Run Code Online (Sandbox Code Playgroud)
产量
//table[@class="last"]
Run Code Online (Sandbox Code Playgroud)
请注意,在这种特殊情况下,如果您不想使用 selenium,您可以使用pytz自行解析和转换时间:
import dateutil.parser as parser
import pytz
text = 'Tue Jul 30 20:00:00 EDT 2013'
date = parser.parse(text)
date = date.replace(tzinfo=None)
print(date.strftime('%I:%M %p'))
# 08:00 PM
ny = pytz.timezone('America/New_York')
london = pytz.timezone('Europe/London')
london_date = ny.localize(date).astimezone(london)
print(london_date.strftime('%I:%M %p'))
# 01:00 AM
Run Code Online (Sandbox Code Playgroud)