刮擦由-tags分隔的列表

时间:2017-11-24 23:41:34

标签: python web-scraping scrapy

我需要抓一个网站,其中包含一个使用非常不合适格式的列表:

<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() )。除此之外,我确信必须有一个更好的解决方案,但我似乎无法找到它是什么。

非常感谢任何帮助!

2 个答案:

答案 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指出我正确的方向!