首页 > 解决方案 > Scrapy 不会使用标准文件管道下载文件

问题描述

我正在尝试从大学Moodle下载所有文件,这些文件是按课程组织的。我已成功登录并以正确的顺序找到文件的所有链接;当我将链接传递给parse_files函数时,什么都没有下载,我得到了这个输出:

    2018-07-11 21:56:41 [scrapy.core.engine] DEBUG: Crawled (200) <GET     https://moodle.some.ac.il/course/view.php?id=1032> (referer: https://moodle.some.ac.il/my/)
        2018-07-11 21:56:41 [scrapy.core.scraper] DEBUG: Scraped from <200 https://moodle.some.ac.il/course/view.php?id=1032>
        {'files_urls': ['https://moodle.some.ac.il/course/view.php?id=1032#section-0']}2018-07-11 21:56:44 [scrapy.core.engine] INFO: Closing spider (finished)
2018-07-11 21:56:44 [scrapy.statscollectors] INFO: Dumping Scrapy stats:
{'downloader/request_bytes': 5944,
 'downloader/request_count': 18,
 'downloader/request_method_count/GET': 17,
 'downloader/request_method_count/POST': 1,
 'downloader/response_bytes': 220875,
 'downloader/response_count': 18,
 'downloader/response_status_count/200': 16,
 'downloader/response_status_count/303': 2,
 'finish_reason': 'finished',
 'finish_time': datetime.datetime(2018, 7, 11, 18, 56, 44, 591156),
 'item_scraped_count': 13,
 'log_count/DEBUG': 32,
 'log_count/INFO': 7,
 'memusage/max': 53354496,
 'memusage/startup': 53354496,
 'request_depth_max': 2,
 'response_received_count': 16,
 'scheduler/dequeued': 17,
 'scheduler/dequeued/memory': 17,
 'scheduler/enqueued': 17,
 'scheduler/enqueued/memory': 17,
 'start_time': datetime.datetime(2018, 7, 11, 18, 56, 37, 753571)}
2018-07-11 21:56:44 [scrapy.core.engine] INFO: Spider closed (finished)

我在启用它并在我的设置中设置后使用内置文件管道FILES_STORE = 'files'。我可能遗漏了一些东西,或者可能与每个文件链接https://moodle.some.ac.il/course/view.php?id=1032#section-0指向的事实有关,https://moodle.some.ac.il/pluginfile.php/44033/mod_resource/content/1/my_file.docx并且蜘蛛无法解决重定向链接?也许有更好的方法吗?非常感谢。这是我的蜘蛛:

import scrapy
import os
import college_files.items as my_item


class CollegeSpider(scrapy.Spider):

name = 'college_spider'

start_urls = ['https://moodle.somecollege.com']


if not os.path.exists('files'):
    os.makedirs("files")



def parse(self, response):

    return scrapy.FormRequest.from_response(
            response,
            formdata={'username': 'my_username', 'password': 'my_password'},
            callback=self.after_login
    )

def after_login(self, response):
    user_name = response.xpath('//div/header/div/div/h1/text()').extract()

    cursos_first = response.css('div.well')
    if not os.path.exists(myFilesDir):
        os.makedirs(myFilesDir)

    for my_course in cursos_first.css('a'):
        my_course_dir = os.path.join(myFilesDir, my_course.css('a::text').extract_first())

        if not os.path.exists(my_course_dir):
            os.makedirs(my_course_dir)
        yield response.follow(my_course.css('a::attr(href)').extract_first(), callback=self.parse_files)
        print("Despues1 {0}".format(my_course))


def parse_files(self, response):
    topics = response.css('ul.topics')
    sections = topics.css('li.section')
    my_i = my_item.FileToDown()
    my_i['files_urls'] = [sections.css('a::attr(href)').extract_first()]
    yield my_i

标签: pythonweb-crawlerscapy

解决方案


如果没有更多信息,真的很难说,如果没有我自己的 moogle 帐户,我将无法获得这些信息,但如果问题scrapy 无法自动解决重定向,您可能需要添加一个额外的步骤您的抓取管道在请求https://moodle.some.ac.il/course/view.php?id=1032#section-0后构建对文件真实位置的请求。

总而言之,这个想法是编写一个函数来响应请求链接,如https://moodle.some.ac.il/course/view.php?id=1032#section-0并使用 this响应构建对链接的请求,例如https://moodle.some.ac.il/pluginfile.php/44033/mod_resource/content/1/my_file.docx,然后由您的函数处理其响应parse_files

要弄清楚这个中间函数必须做什么才能提交对所需文件 url 的请求,我建议检查将传递给中间函数的响应主体,并将 xpath 定位到文件 url 所在的位置。


推荐阅读