我需要抓一个网站,其中包含一个使用非常不合适格式的列表:
<div class="post">
<b>FIELD1</b><br/>FIELD2<br/>FIELD3<br/><br/>
<b>FIELD1</b><br/>FIELD2<br/>FIELD3<br/><br/>
<b>FIELD1</b><br/>FIELD2<br/>FIELD3<br/><br/>
</div>
即,所有内容都由<br/>
- 标签分隔。可以通过元素末尾的双<br/>
标记来标识新元素,新元素以<br/>
标记开头。更糟糕的是,FIELD3还可能包含<br/>
个标签。换句话说,FIELD2是&#34;关闭</b>
标签后的字段&#34;而FIELD3是&#34;双<br/>
标记之前的字段。
这是我到目前为止所做的:
由于我找不到抓住FIELD2和FIELD3的好方法,我尝试用<p>
和{{替换</b><br/>
来围绕FIELD2和3创建</b><p>
标记。 1}}与<br/><br/>
:
<br/><p>
但是,这不起作用(def parse(self, response):
items = response.xpath('//div[@id="mainDiv"]/div[1]')
items = str.replace(items, "</b><br/>", "</b><p>")
items = str.replace(items, "<br/><br/>", "</p><br/>")
for item in items :
dateX = item.xpath('.//b/text()').extract()
infoX = item.xpath('.//p/text()').extract()
)。除此之外,我确信必须有一个更好的解决方案,但我似乎无法找到它是什么。
非常感谢任何帮助!
答案 0 :(得分:1)
这个(或接近它的东西):
def parse(self, response):
posts = response.xpath('//div[@id="mainDiv"]/div[@class="post"]')
for post in posts:
field1 = post.xpath('./b/text()').extract()
field2 = post.xpath('./br[1]/following-sibling::text()[1]').extract()
field3 = post.xpath('./br[2]/following-sibling::text()[1]').extract()
关键点是:不要在HTML上使用字符串函数(split,regex,search和replace)。这是一个始终适用的规则,但是当您已经拥有一个具有XPath支持的完全解析的DOM树时,这是一个双倍的规则。树中的任何节点都有一个XPath表达式。
答案 1 :(得分:0)
这就是诀窍:
def parse(self, response):
items = response.xpath('//div[@id="mainDiv"]/div[1]')
for item in items :
i=1
while (i < 10):
field1 = item.xpath('.//b['+str(i)+']/text()').extract()
field2 = item.xpath('.//b['+str(i)+']/following-sibling::text()[1]').extract()
field3 = item.xpath('.//b['+str(i)+']/following-sibling::text()[2]').extract()
yield {
'field1': field1
,'field2': field2
,'field3': field3
}
i=i+1
现在唯一要做的就是替换i&lt; 10,正确的总数,但这应该很容易。
再次感谢@Tomalak指出我正确的方向!