从抓取的项目中提取日期和其他数据
Extracting date and other data from scraped items
我正在编写 Python 代码,使用 lxml、urllib 和 csv 来抓取 a Brazil government site 中的演讲。
我能够使用 XPath 找到每个演讲的标题和 link,但找不到确切的日期,因为演讲日期之前没有特定的标签。
当我使用 XPath '//span[@class="summary-view-icon"]/text()
时,抓取器带回了日期、时间和单词“Página”(页面,葡萄牙语)。我知道这个Xpath不对,但是我不知道如何select只有一天。
即使有这个错误,我还是能够将 抓取的 内容转换为列表并编辑以删除除日期以外的所有内容。问题是最终列表,如下所示,还有一些我无法删除的其他字符。
这里似乎有两个解决方案:正确设置 XPath 或删除列表中的其他字符。我该怎么做?
['\n 18/12/2015\n', '\n 21/12/2015\n', '\n 21/12/2015\n', '\ n 22/12/2015\n ', '\n 22/12/2015\n ', '\n 22/12/2015\n ', '\n 11/01/2016\n ', '\n 19/01/2016\n ', '\n 21/01/2016\n ', '\n 26/01/2016\n ', '\n 27/01/2016\n ', '\n 27/01/2016\n ', '\n 28/01/2016\n ] ', '\n 01/02/2016\n ', '\n 01/02/2016\n ', '\n 02/02/2016\n ', '\n 02/ 02/2016\n ', '\n 02/02/2016\n ', '\n 03/02/2016\n ', '\n 03/02/2016\n ', '\n 19/02/2016\n ', '\n 19/02/2016\n ', '\n 22/02/2016\n ', '\n 26/02/2016\n ', '\n 26/02/2016\n ', '\n 02/ 03/2016\n ', '\n 03/03/2016\n ', '\n 04/03/2016\n ', '\n 07/03/2016\n ', '\n 04/02/2016\n ', '\n 08/03/2016\n ', '\n 09/03/2016\n ', '\n 17/03/2016\n ', '\n 18/03/2016\n ', '\n 22/ 03/2016\n ', '\n 23/03/2016\n ', '\n 23/03/2016\n ', '\n30/03/2016\n ', '\n 31/03/2016\n ', '\n 01/04/2016\n ']
您可以使用 strip
:
从列表中的元素中删除所有换行符/空格
new_list = [item.strip() for item in old_list]
编辑:您说您能够将结果转换为问题中的列表,在这种情况下,您可以只删除那里的元素。
尝试使用以下 XPath 将结果缩小到只有日期:
//span[@class="summary-view-icon"][i/@class="icon-day"]/text()[normalize-space()]
上述XPath的最后一位(text()[normalize-space()]
) returns只有非空个文本节点。从这里开始,您仍然需要使用 strip()
:
删除不必要的空格
query = '//span[@class="summary-view-icon"][i/@class="icon-day"]/text()[normalize-space()]'
dates = root.xpath(query)
result = [date.strip() for date in dates]
这里使用 regular expression:
dates = [re.search(r'\d{2}/\d{2}/\d{4}', item, re.MULTILINE).group(0) for item in old_list]
给出:
['18/12/2015', '21/12/2015', '21/12/2015', '22/12/2015', '22/12/2015',
'22/12/2015', '11/01/2016', '19/01/2016', '21/01/2016', '26/01/2016',
'27/01/2016', '27/01/2016', '28/01/2016', '01/02/2016', '01/02/2016',
'02/02/2016', '02/02/2016', '02/02/2016', '03/02/2016', '03/02/2016',
'19/02/2016', '19/02/2016', '22/02/2016', '26/02/2016', '26/02/2016',
'02/03/2016', '03/03/2016', '04/03/2016', '07/03/2016', '04/02/2016',
'08/03/2016', '09/03/2016', '17/03/2016', '18/03/2016', '22/03/2016',
'23/03/2016', '23/03/2016', '30/03/2016', '31/03/2016', '01/04/2016']
这可能有助于处理具有更多差异或意外格式的数据。
这会让你得到你想要的:
items = response.xpath('//div[@id="content-core"]//div[contains(@class, "tileItem")]')
for item in items:
date = item.xpath('normalize-space(.//span[@class="summary-view-icon"][i[@class="icon-day"] ]//text()[normalize-space()])')
使用 normalize-space 两次将剥离删除空结果 + 剥离最终结果的所有白色spaces。
您可以使用正则表达式以您想要的格式提取日期,无需额外字符。
基于页面结构,我开发了一个 scraper,使用 re 来演示我将如何做:
import requests, re
from lxml import etree
def get_speeach_data(item):
title = item.xpath('.//h2[@class="tileHeadline"]/a/text()')[0]
sidebar = item.xpath('./span[@class="documentByLine"]')[0]
sidebar_html = etree.tostring( sidebar )
m = re.search(r'(\d+/\d+/\d+)', sidebar_html)
date = m.group(1)
m = re.search(r'(\d+h\d+)', sidebar_html)
hour = m.group(1)
return { 'title' : title, 'date' : date, 'hour' : hour }
if __name__ == '__main__':
url = 'http://www2.planalto.gov.br/acompanhe-o-planalto/discursos/discursos-da-presidenta?b_start:int=0'
r = requests.get( url )
if r.status_code == 200:
page = etree.HTML( r.content )
raw_speeaches = page.xpath('//*[@id="content-core"]/div')
speeaches = map(get_speeach_data, raw_speeaches)
print speeaches
我正在编写 Python 代码,使用 lxml、urllib 和 csv 来抓取 a Brazil government site 中的演讲。
我能够使用 XPath 找到每个演讲的标题和 link,但找不到确切的日期,因为演讲日期之前没有特定的标签。
当我使用 XPath '//span[@class="summary-view-icon"]/text()
时,抓取器带回了日期、时间和单词“Página”(页面,葡萄牙语)。我知道这个Xpath不对,但是我不知道如何select只有一天。
即使有这个错误,我还是能够将 抓取的 内容转换为列表并编辑以删除除日期以外的所有内容。问题是最终列表,如下所示,还有一些我无法删除的其他字符。
这里似乎有两个解决方案:正确设置 XPath 或删除列表中的其他字符。我该怎么做?
['\n 18/12/2015\n', '\n 21/12/2015\n', '\n 21/12/2015\n', '\ n 22/12/2015\n ', '\n 22/12/2015\n ', '\n 22/12/2015\n ', '\n 11/01/2016\n ', '\n 19/01/2016\n ', '\n 21/01/2016\n ', '\n 26/01/2016\n ', '\n 27/01/2016\n ', '\n 27/01/2016\n ', '\n 28/01/2016\n ] ', '\n 01/02/2016\n ', '\n 01/02/2016\n ', '\n 02/02/2016\n ', '\n 02/ 02/2016\n ', '\n 02/02/2016\n ', '\n 03/02/2016\n ', '\n 03/02/2016\n ', '\n 19/02/2016\n ', '\n 19/02/2016\n ', '\n 22/02/2016\n ', '\n 26/02/2016\n ', '\n 26/02/2016\n ', '\n 02/ 03/2016\n ', '\n 03/03/2016\n ', '\n 04/03/2016\n ', '\n 07/03/2016\n ', '\n 04/02/2016\n ', '\n 08/03/2016\n ', '\n 09/03/2016\n ', '\n 17/03/2016\n ', '\n 18/03/2016\n ', '\n 22/ 03/2016\n ', '\n 23/03/2016\n ', '\n 23/03/2016\n ', '\n30/03/2016\n ', '\n 31/03/2016\n ', '\n 01/04/2016\n ']
您可以使用 strip
:
new_list = [item.strip() for item in old_list]
编辑:您说您能够将结果转换为问题中的列表,在这种情况下,您可以只删除那里的元素。
尝试使用以下 XPath 将结果缩小到只有日期:
//span[@class="summary-view-icon"][i/@class="icon-day"]/text()[normalize-space()]
上述XPath的最后一位(text()[normalize-space()]
) returns只有非空个文本节点。从这里开始,您仍然需要使用 strip()
:
query = '//span[@class="summary-view-icon"][i/@class="icon-day"]/text()[normalize-space()]'
dates = root.xpath(query)
result = [date.strip() for date in dates]
这里使用 regular expression:
dates = [re.search(r'\d{2}/\d{2}/\d{4}', item, re.MULTILINE).group(0) for item in old_list]
给出:
['18/12/2015', '21/12/2015', '21/12/2015', '22/12/2015', '22/12/2015',
'22/12/2015', '11/01/2016', '19/01/2016', '21/01/2016', '26/01/2016',
'27/01/2016', '27/01/2016', '28/01/2016', '01/02/2016', '01/02/2016',
'02/02/2016', '02/02/2016', '02/02/2016', '03/02/2016', '03/02/2016',
'19/02/2016', '19/02/2016', '22/02/2016', '26/02/2016', '26/02/2016',
'02/03/2016', '03/03/2016', '04/03/2016', '07/03/2016', '04/02/2016',
'08/03/2016', '09/03/2016', '17/03/2016', '18/03/2016', '22/03/2016',
'23/03/2016', '23/03/2016', '30/03/2016', '31/03/2016', '01/04/2016']
这可能有助于处理具有更多差异或意外格式的数据。
这会让你得到你想要的:
items = response.xpath('//div[@id="content-core"]//div[contains(@class, "tileItem")]')
for item in items:
date = item.xpath('normalize-space(.//span[@class="summary-view-icon"][i[@class="icon-day"] ]//text()[normalize-space()])')
使用 normalize-space 两次将剥离删除空结果 + 剥离最终结果的所有白色spaces。
您可以使用正则表达式以您想要的格式提取日期,无需额外字符。
基于页面结构,我开发了一个 scraper,使用 re 来演示我将如何做:
import requests, re
from lxml import etree
def get_speeach_data(item):
title = item.xpath('.//h2[@class="tileHeadline"]/a/text()')[0]
sidebar = item.xpath('./span[@class="documentByLine"]')[0]
sidebar_html = etree.tostring( sidebar )
m = re.search(r'(\d+/\d+/\d+)', sidebar_html)
date = m.group(1)
m = re.search(r'(\d+h\d+)', sidebar_html)
hour = m.group(1)
return { 'title' : title, 'date' : date, 'hour' : hour }
if __name__ == '__main__':
url = 'http://www2.planalto.gov.br/acompanhe-o-planalto/discursos/discursos-da-presidenta?b_start:int=0'
r = requests.get( url )
if r.status_code == 200:
page = etree.HTML( r.content )
raw_speeaches = page.xpath('//*[@id="content-core"]/div')
speeaches = map(get_speeach_data, raw_speeaches)
print speeaches