Scrapy - 格式化内容和HTML属性
我正在用Scrapy抓取一个网站的数据,准备导入,但在处理内部链接的格式时遇到了一些麻烦。
看看下面这个HTML结构:
<div class="PageContent">
<a href="files/documents/path1.pdf">Click me</a>
<a href="files/documents/path2.pdf">Click me</a>
<a href="files/documents/path3.pdf">Click me</a>
</div>
这是我使用的XPath:
item["page_content"] = response.xpath("//div[@class='PageContent']".encode("ascii","ignore"))[0].extract().replace('\r','')
这个方法效果不错。我还检查了响应中是否有文件,并且也下载了它们。我对FilesPipeline进行了定制,让它保留相对路径和文件名,而不是把它们变成一个GUID。
pdf_urls = nodes.xpath(u'//a[@href[contains(., ".pdf")]]/@href'.encode("utf-8")).extract()
这个部分也运行得很好。
我需要做的是修改item["page_content"]
,在HREF属性的前面加上一个字符串,如果文件扩展名是.PDF的话。我尝试过这个(还有各种不同的版本):
for attr in response.xpath(u'//a[@href[contains(., ".pdf")]]/@href'):
attr[href] = "/new/dir/in/front" + attr
但都没有成功。而且,即使我成功修改了这些数据,怎么才能让items["page_content"]
不变成一个包含这些新属性的列表呢?我想要的结果是:
items["page_content"] = <div class="PageContent">
<a href="/new/dir/in/front/files/documents/path1.pdf">Click me</a>
<a href="/new/dir/in/front/files/documents/path2.pdf">Click me</a>
<a href="/new/dir/in/front/files/documents/path3.pdf">Click me</a>
</div>
提前谢谢你!
2 个回答
0
你有没有试过手动生成 items["page_content"] 呢?可以试试像这样:
items['page_content'] = []
for attr in response.xpath(u'//a[@href[contains(., ".pdf")]]/@href'):
items['page_content'].append("/new/dir/in/front" + attr)
1
我试了很久这个问题,最后决定用一个XML/HTML解析器来整理我的数据。这样做简单多了,速度也快,而且控制得更好。把这个答案发出来,希望能帮助到遇到类似问题的人。
这里有一段代码:
from lxml import html as HTML
from lxml import etree as ET
...
doc_pattern = ('//a[@href['
' contains(., ".pdf") or'
' contains(., ".dot") or'
' contains(., ".rtf") or'
' contains(., ".doc") or'
' contains(., ".xls") or'
' contains(., ".docx") or'
' contains(., ".xlsx")'
']]')
def parse_page_html(pattern,
response=response,
HTML=HTML,
ET=ET
):
parser = ET.HTMLParser(remove_comments=True, remove_blank_text=True)
content = response.xpath(pattern)[0].extract()
content = content.encode("ascii","ignore")
content = content.replace('\r','').replace('\n','').replace('\t','')
body = HTML.fromstring(content, parser=parser)
for links in body.xpath(doc_pattern):
links.attrib['href'] = remove_absolute_url( links.attrib['href'] )
...
content = ET.tostring(body)
return content
我之前从来没有做过这样的事情(而且只用Python学了大约3个小时),但是lxml让我在不到45分钟内就上手了。我最后重写了很多代码来利用这个工具,结果非常棒。