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]

也许你应该
提供
内部
-谢谢,这很有意义。这是一个简单的解决方案,但因为我还在学习,所以我一直在努力寻找它。