在 Scrapy 中使用 ItemLoaders() 下载文件
Downloading files with ItemLoaders() in Scrapy
我创建了一个爬行蜘蛛来下载文件。然而,蜘蛛只下载了文件的 url,而不是文件本身。我在这里 上传了一个问题。虽然答案中善意建议的基本 yield spider 工作得很好,但当我尝试使用 items 或 item loaders 下载文件时,spider 不起作用!原题不包括items.py。所以它是:
项目
import scrapy
from scrapy.item import Item, Field
class DepositsusaItem(Item):
# main fields
name = Field()
file_urls = Field()
files = Field()
# Housekeeping Fields
url = Field()
project = Field()
spider = Field()
server = Field()
date = Field()
pass
编辑: 添加原始代码
编辑:进一步更正
蜘蛛
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
import datetime
import socket
from us_deposits.items import DepositsusaItem
from scrapy.loader import ItemLoader
from scrapy.loader.processors import MapCompose
from urllib.parse import urljoin
class DepositsSpider(CrawlSpider):
name = 'deposits'
allowed_domains = ['doi.org']
start_urls = ['https://minerals.usgs.gov/science/mineral-deposit-database/#products', ]
rules = (
Rule(LinkExtractor(restrict_xpaths='//*[@id="products"][1]/p/a'),
callback='parse_x'),
)
def parse_x(self, response):
i = ItemLoader(item=DepositsusaItem(), response=response)
i.add_xpath('name', '//*[@class="container"][1]/header/h1/text()')
i.add_xpath('file_urls', '//span[starts-with(@data-url, "/catalog/file/get/")]/@data-url',
MapCompose(lambda i: urljoin(response.url, i))
)
i.add_value('url', response.url)
i.add_value('project', self.settings.get('BOT_NAME'))
i.add_value('spider', self.name)
i.add_value('server', socket.gethostname())
i.add_value('date', datetime.datetime.now())
return i.load_item()
设置
BOT_NAME = 'us_deposits'
SPIDER_MODULES = ['us_deposits.spiders']
NEWSPIDER_MODULE = 'us_deposits.spiders'
ROBOTSTXT_OBEY = False
ITEM_PIPELINES = {
'us_deposits.pipelines.UsDepositsPipeline': 1,
'us_deposits.pipelines.FilesPipeline': 2
}
FILES_STORE = 'C:/Users/User/Documents/Python WebCrawling Learning Projects'
管道
class UsDepositsPipeline(object):
def process_item(self, item, spider):
return item
class FilesPipeline(object):
def process_item(self, item, spider):
return item
在我看来,使用项目 and/or 项目加载器与您的问题无关。
我看到的唯一问题是在您的设置文件中:
FilesPipeline
未激活(只有us_deposits.pipelines.UsDepositsPipeline
激活)
FILES_STORE
应该是一个字符串,而不是一个集合(激活文件管道时会引发异常)
ROBOTSTXT_OBEY = True
将阻止下载文件
如果我更正所有这些问题,文件下载将按预期进行。
我创建了一个爬行蜘蛛来下载文件。然而,蜘蛛只下载了文件的 url,而不是文件本身。我在这里
项目
import scrapy
from scrapy.item import Item, Field
class DepositsusaItem(Item):
# main fields
name = Field()
file_urls = Field()
files = Field()
# Housekeeping Fields
url = Field()
project = Field()
spider = Field()
server = Field()
date = Field()
pass
编辑: 添加原始代码 编辑:进一步更正
蜘蛛
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
import datetime
import socket
from us_deposits.items import DepositsusaItem
from scrapy.loader import ItemLoader
from scrapy.loader.processors import MapCompose
from urllib.parse import urljoin
class DepositsSpider(CrawlSpider):
name = 'deposits'
allowed_domains = ['doi.org']
start_urls = ['https://minerals.usgs.gov/science/mineral-deposit-database/#products', ]
rules = (
Rule(LinkExtractor(restrict_xpaths='//*[@id="products"][1]/p/a'),
callback='parse_x'),
)
def parse_x(self, response):
i = ItemLoader(item=DepositsusaItem(), response=response)
i.add_xpath('name', '//*[@class="container"][1]/header/h1/text()')
i.add_xpath('file_urls', '//span[starts-with(@data-url, "/catalog/file/get/")]/@data-url',
MapCompose(lambda i: urljoin(response.url, i))
)
i.add_value('url', response.url)
i.add_value('project', self.settings.get('BOT_NAME'))
i.add_value('spider', self.name)
i.add_value('server', socket.gethostname())
i.add_value('date', datetime.datetime.now())
return i.load_item()
设置
BOT_NAME = 'us_deposits'
SPIDER_MODULES = ['us_deposits.spiders']
NEWSPIDER_MODULE = 'us_deposits.spiders'
ROBOTSTXT_OBEY = False
ITEM_PIPELINES = {
'us_deposits.pipelines.UsDepositsPipeline': 1,
'us_deposits.pipelines.FilesPipeline': 2
}
FILES_STORE = 'C:/Users/User/Documents/Python WebCrawling Learning Projects'
管道
class UsDepositsPipeline(object):
def process_item(self, item, spider):
return item
class FilesPipeline(object):
def process_item(self, item, spider):
return item
在我看来,使用项目 and/or 项目加载器与您的问题无关。
我看到的唯一问题是在您的设置文件中:
FilesPipeline
未激活(只有us_deposits.pipelines.UsDepositsPipeline
激活)FILES_STORE
应该是一个字符串,而不是一个集合(激活文件管道时会引发异常)ROBOTSTXT_OBEY = True
将阻止下载文件
如果我更正所有这些问题,文件下载将按预期进行。