我目前正在使用
处理文档<b> label1 </b>
value1 <br>
<b> label2 </b>
value2 <br>
....
我无法通过scrapy找出xpath的干净方法。 这是我最好的实现
hxs = HtmlXPathSelector(response)
section = hxs.select(..............)
values = section.select("text()[preceding-sibling::b/text()]"):
labels = section.select("text()/preceding-sibling::b/text()"):
但我不满意这种通过索引匹配两个列表的节点的方法。我宁愿遍历1个列表(值或标签)并将匹配的节点作为相对xpath进行查询。如:
values = section.select("text()[preceding-sibling::b/text()]"):
for value in values:
value.select("/preceding-sibling::b/text()"):
我一直在调整这个表达式,但总是不返回匹配
更新
我正在寻找能够容忍“噪音”的稳健方法,例如:
garbage1<br>
<b> label1 </b>
value1 <br>
<b> label2 </b>
value2 <br>
garbage2<br>
<b> label3 </b>
value3 <br>
<div>garbage3</div>
答案 0 :(得分:1)
编辑:抱歉,我使用lxml,但它对Scrapy自己的选择器也一样。
对于您提供的特定HTML,这将起作用:
>>> s = """<b> label1 </b>
... value1 <br>
... <b> label2 </b>
... value2 <br>
... """
>>>
>>> import lxml.html
>>> lxml.html.fromstring(s)
<Element span at 0x10fdcadd0>
>>> soup = lxml.html.fromstring(s)
>>> soup.xpath("//text()")
[' label1 ', '\nvalue1 ', ' label2 ', '\nvalue2 ']
>>> res = soup.xpath("//text()")
>>> for i in xrange(0, len(res), 2):
... print res[i:i+2]
...
[' label1 ', '\nvalue1 ']
[' label2 ', '\nvalue2 ']
>>>
编辑2:
>>> bs = etree.xpath("//text()[preceding-sibling::b/text()]")
>>> for b in bs:
... if b.getparent().tag == "b":
... print [b.getparent().text, b]
...
[' label1 ', '\nvalue1 ']
[' label2 ', '\nvalue2 ']
[' label3 ', '\nvalue3 ']
另外,对于它的价值,如果你循环选择的元素,你想在for循环中的xpath中执行“./foo”,而不是“/ foo”。