在Python中使用Scrapy解析时保留换行符

时间:2012-01-05 18:50:35

标签: python web-scraping scrapy

我写了一个Scrapy蜘蛛,它从页面中提取文本。蜘蛛在许多页面上正确地解析和输出,但是被一些页面抛弃了。我正在尝试在文档中维护换行符和格式。像http://www.state.gov/r/pa/prs/dpb/2011/04/160298.htm这样的页面格式正确如下:

  

2011年4月7日

     

Mark C. Toner

     

下午2:03 EDT

     

MR。 TONER:大家下午好。顶部有几件事,   然后我,你会回答你的问题。我们谴责对无辜者的袭击   以色列南部的平民也是最强烈的条件   正在进行的加沙火箭射击。正如我们多次重申的那样,   在那里,没有理由以无辜平民为目标,   应该举行那些应对这些恐怖主义行为负责的人   问责。我们特别关注有迹象表明的报道   在对平民的袭击中使用先进的反坦克武器   并重申所有国家都有相关的义务   联合国安理会关于防止非法的决议   贩运武器和弹药。也只是一个简短的陈述 -

     

问题:我们能坚持一秒钟吗?

     

MR。 TONER:是的。来吧,马特。

     

问题:显然,目标是校车。那样做   加入你的愤怒?

     

MR。 TONER:嗯,对无辜平民的任何攻击都是令人憎恶的,但是   当然,攻击的性质尤其如此。

虽然像http://www.state.gov/r/pa/prs/dpb/2009/04/121223.htm这样的网页输出如此,没有换行符:

  

2009年4月2日

     罗伯特伍德

     

EDTMR上午11:53。伍德:大家早上好。我认为,只是   还是早上好。欢迎来到简报。我没有,有什么,   所以,先生。问题:朝鲜人已经开始为油轮加油,或者   无论如何,靠近网站。他们可能会也可能不会加油   导弹。你对朝鲜人有什么智慧的话语   这一刻?MR。伍德:嗯,马特,我,你不会发表评论   知道,情报很重要。但是,我再说一遍,我们呼吁   北方不再发射任何类型的导弹。这将是   适得其反。它具有挑衅性。它进一步加剧了紧张局势   该区域。我们希望看到北方回到六方   框架和重点是无核化。是的。问题:日本也有   他们说,他们将要求在安全部门召开紧急会议   你知道,理事会应该继续推出。这是什么东西   你也想找?MR。伍德:嗯,让我们看看这个测试   发生。我们当然希望它没有。再一次,呼唤北方   不要这样做。但当然,我们会,如果测试确实进展,   我们将与盟友进行讨论。

我正在使用的代码如下:

def parse_item(self, response):
    self.log('Hi, this is an item page! %s' % response.url) 

    hxs = HtmlXPathSelector(response)

    speaker = hxs.select("//span[contains(@class, 'official_s_name')]") #gets the speaker
    speaker = speaker.select('string()').extract()[0] #extracts speaker text
    date = hxs.select('//*[@id="date_long"]') #gets the date
    date = date.select('string()').extract()[0] #extracts the date
    content = hxs.select('//*[@id="centerblock"]') #gets the content
    content = content.select('string()').extract()[0] #extracts the content

    texts = "%s\n\n%s\n\n%s" % (date, speaker, content) #puts everything together in a string

    filename = ("/path/StateDailyBriefing-" + '%s' ".txt") % (date) #creates a file using the date

    #opens the file defined above and writes 'texts' using utf-8
    with codecs.open(filename, 'w', encoding='utf-8') as output:
        output.write(texts)

我认为他们的问题在于页面HTML的格式化。在错误输出文本的页面上,段落由<br> <p></p>分隔,而在正确输出的页面上,段落包含在<p align="left" dir="ltr">中。所以,虽然我已经确定了这一点,但我不确定如何以正确的形式一致地输出所有内容。

2 个答案:

答案 0 :(得分:6)

问题在于,当您收到text()string()时,<br>代码未转换为换行符。

解决方法 - 在执行XPath请求之前替换<br>标记。代码:

response = response.replace(body=response.body.replace('<br />', '\n')) 
hxs = HtmlXPathSelector(response)

如果您知道,只有一个节点,我可以提供一些建议,您可以使用text()代替string()

date = hxs.select('//*[@id="date_long"]/text()').extract()[0]

答案 1 :(得分:3)

试试这个xpath:

//*[@id="centerblock"]//text()