我试图实现一个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()')
随着BeautifulSoup:
table = soup.find('table', attrs={'id':'tradingHours'})
for td in table.findChildren('td'):
print td.text
什么是实现这一目标的最佳方法是什么? 我想用lxml
不beautifulSoup
(刚刚看到的差异)。
你lxml
代码是非常接近的工作。 主要的问题是table
标签是不是一个与class="last"
属性。 相反,它是一个tr
是有属性的标签:
</tr><tr class="last"><td>TRADING HOURS</td>
从而,
//table[@class="last"]
没有比赛。 还有一个较小的语法错误: @id"tradingHours"
应该是@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())
的石斑鱼配方 , 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)
我不是在解释石斑鱼食谱是如何工作的非常好,但是我做了一个在这里尝试 。
该页面使用JavaScript来格式化日期。 刮页面JavaScript的已经改变了内容之后 ,你可以使用硒 :
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)
产量
NEW YORK
8:00 PM-2:15 PM *
20:00-14:15
7:30 PM
19:30
--------------------------------------------------------------------------------
LONDON
1:00 AM-7:15 PM
01:00-19:15
12:30 AM
00:30
--------------------------------------------------------------------------------
SINGAPORE
8:00 AM-2:15 AM *
08:00-02:15
7:30 AM
07:30
--------------------------------------------------------------------------------
请注意,在这种特殊情况下,如果你不想使用硒,你可以使用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
我喜欢的CSS选择上比的XPath页面变化太大适应性:
import urllib
from lxml import html
url = 'https://www.theice.com/productguide/ProductSpec.shtml?specId=251'
response = urllib.urlopen(url).read()
h = html.document_fromstring(response)
for tr in h.cssselect('#tradingHours tbody tr'):
td = tr.cssselect('td')
print td[0].text_content(), td[1].text_content()
如果该网站是正确的HTML,ID属性是独特的,你可以找到在表doc.get_element_by_id('tradingHours')
import urllib
from lxml import html
url = 'https://www.theice.com/productguide/ProductSpec.shtml?specId=251'
response = urllib.urlopen(url).read()
h = html.document_fromstring(response)
print "BY ID"
tradingHours = h.get_element_by_id('tradingHours')
for tr in tradingHours.xpath('tbody/tr'):
tds = tr.xpath('td')
print tds[0].text.strip()
for td in tds[1:]:
print ' ', td.text.strip()
结果是
BY ID
NEW YORK
Tue Jul 30 20:00:00 EDT 2013-Tue Jul 30 14:15:00 EDT 2013 *
Tue Jul 30 19:30:00 EDT 2013
LONDON
Tue Jul 30 20:00:00 EDT 2013-Tue Jul 30 14:15:00 EDT 2013
Tue Jul 30 19:30:00 EDT 2013
SINGAPORE
Tue Jul 30 20:00:00 EDT 2013-Tue Jul 30 14:15:00 EDT 2013 *
Tue Jul 30 19:30:00 EDT 2013