python - 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
解决方案
如果没有更多信息,真的很难说,如果没有我自己的 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 所在的位置。
推荐阅读
- php - 使用 php/guzzle 从 uri 获取 Json
- powerbi - Power BI API - 如何从 app.powerbi.com 获取报告?
- sql - 查找前 N 个最频繁的类别以及每个类别的前 N 个最频繁的子类别
- c# - Linq 表达式树编译非平凡的对象常量并以某种方式引用它们
- list - OCaml 检查元组右侧是否存在元素
- angular - 如何在 Angular 6 中使用 ngModel 时默认选择标签中的值?
- mysql-workbench - 如何将空间数据导入 mysql 8 (Mysql WorkBench 8.0)
- c++ - EthernetInterface 实例中断程序
- sql-server - 多列重叠日期
- php - Checking an array value that isn't a number