Python 列出几个绝对URL“;urljoin';教育署;
我想从第一篇帖子下载所有的文件,其中有几个特定论坛的主题。我设置了自己的文件管道,将项目Python 列出几个绝对URL“;urljoin';教育署;,python,scrapy,Python,Scrapy,我想从第一篇帖子下载所有的文件,其中有几个特定论坛的主题。我设置了自己的文件管道,将项目文件url、文件名和源代码(主题名)保存到文件夹/source/file\u name 但是,文件链接是相对的,我需要使用绝对路径。我尝试了response.urljoin,它给了我一个字符串,表示绝对url,但只表示文章的最后一个文件 运行spider时会出现错误ValueError:请求url:h中缺少方案 这是因为绝对url是字符串而不是列表 这是我的密码: import scrapy from ..i
文件url
、文件名
和源代码
(主题名)保存到文件夹/source/file\u name
但是,文件链接是相对的,我需要使用绝对路径。我尝试了response.urljoin
,它给了我一个字符串
,表示绝对url,但只表示文章的最后一个文件
运行spider时会出现错误ValueError:请求url:h中缺少方案
这是因为绝对url是字符串
而不是列表
这是我的密码:
import scrapy
from ..items import FilespipelineItem
class MTGSpider (scrapy.Spider):
name = 'mtgd'
base_url = 'https://www.slightlymagic.net/forum'
subforum_url = '/viewforum.php?f=48'
start_urls = [base_url + subforum_url]
def parse(self, response):
for topic_url in response.css('.row dl dt a.topictitle::attr(href)').extract():
yield response.follow(topic_url, callback=self.parse_topic)
def parse_topic(self, response):
item = FilespipelineItem()
item['source'] = response.xpath('//h2/a/text()').get()
item['file_name'] = response.css('.postbody')[0].css('.file .postlink::text').extract()
# Problematic code
for file_url in response.css('.postbody')[0].css('.file .postlink::attr(href)').extract():
item['file_url'] = response.urljoin(file_url)
yield item
如果有帮助,下面是管道代码:
import re
from scrapy.pipelines.files import FilesPipeline
from scrapy import Request
class MyFilesPipeline(FilesPipeline):
def get_media_requests(self, item, info):
for file_url in item['file_url']:
yield Request(file_url,
meta={
'name': item['file_name'],
'source': item['source']
})
# Rename files to their original name and not the hash
def file_path(self, request, response=None, info=None):
file = request.meta['name']
source = request.meta['source']
# Get names from previous function meta
source = re.sub(r'[?\\*|"<>:/]', '', source)
# Clean source name for windows compatible folder name
filename = u'{0}/{1}'.format(source, file)
# Folder storage key: {0} corresponds to topic name; {1} corresponds to filename
return filename
重新导入
从scrapy.pipelines.files导入文件管道
从刮擦进口请求
类MyFilePipeline(FilePipeline):
def获取媒体请求(自身、项目、信息):
对于项目['file\u url']中的文件\u url:
屈服请求(文件url,
元={
“名称”:项[“文件名”],
“源”:项[“源”]
})
#将文件重命名为其原始名称,而不是哈希值
def文件路径(self、request、response=None、info=None):
file=request.meta['name']
source=request.meta['source']
#从上一个函数元中获取名称
source=re.sub(r'[?\\*.\”:/“,'',source)
#清除windows兼容文件夹名称的源名称
filename=u'{0}/{1}'。格式(源,文件)
#文件夹存储键:{0}对应于主题名;{1}对应于文件名
返回文件名
所以我的问题是
在一个有多个文件要下载的主题中,如何将几个绝对url保存到file\u url
项中?由于for
循环只保存最后一个文件的url,因此无法正常工作
对于此问题,是否需要for
循环?如果需要,应该是什么?在:
用于响应.css('.postbody')[0].css('.file.postlink::attr(href)').extract():
item['file\u url']=response.urljoin(file\u url)
您每次都使用新url覆盖项['file\u url']
,因此最后一个url的值就是保留的值
对循环使用Python列表理解而不是:
file_url=response.css('.postbody')[0].css('.file.postlink::attr(href')).extract():
项['file\u url']=[response.urljoin(file\u url)用于文件\u url中的文件\u url]
也许你应该为
提供内部-谢谢,这很有意义。这是一个简单的解决方案,但因为我还在学习,所以我一直在努力寻找它。