我看到了两种方法
第一:
使用不同的参数多次运行蜘蛛。它将需要更少的代码。
您可以使用手动添加不同参数的多行创建批处理。
第一个参数是输出文件名-o result1.csv,scrapy 会自动创建。
第二个参数是带有链接的输入文件名-a filename=process1.csv。
scrapy crawl hotel_info -o result1.csv -a filename=process1.csv
scrapy crawl hotel_info -o result2.csv -a filename=process2.csv
scrapy crawl hotel_info -o result3.csv -a filename=process3.csv
...
a 它只需要在__init__ 中获取filename
import scrapy
from os.path import isfile, join
import json
class HotelInfoSpider(scrapy.Spider):
name = 'hotel_info'
allowed_domains = ['lastsecond.ir']
def __init__(self, filename, *args, **kwargs): # <-- filename
super().__init__(*args, **kwargs)
filename = join('lastsecond/hotels/', filename)
if isfile(filename):
with open(filename) as f:
data = json.load(f)
self.start_urls = data['links']
def parse(self, response):
print('url:', response.url)
yield {'url':, response.url, 'other': ...}
您还可以使用带有CrawlerProcess 的 Python 脚本多次运行蜘蛛。
from scrapy.crawler import CrawlerProcess
import HotelInfoSpider
from os.path import isfile, join
import json
files = [f for f in listdir('lastsecond/hotels/') if isfile(join('lastsecond/hotels/', f))]
for i, input_file in enumerate(files):
output_file = 'result{}.csv'.format(i)
c = CrawlerProcess({'FEED_FORMAT': 'csv','FEED_URI': output_file})
c.crawl(HotelInfoSpider, filename=input_file) #input_file='process1.csv')
c.start()
或使用scrapy.cmdline.execute()
import scrapy.cmdline
from os.path import isfile, join
import json
files = [f for f in listdir('lastsecond/hotels/') if isfile(join('lastsecond/hotels/', f))]
for i, input_file in enumerate(files):
output_file = 'result{}.csv'.format(i)
scrapy.cmdline.execute(["scrapy", "crawl", "hotel_info", "-o", output_file, "-a" "filename=" + input_file])
第二:
它需要更多代码,因为您必须创建将使用不同文件来保存结果的 Pipeline Exporter。
您必须使用start_requests() 和Request(..., meta=...) 来创建start_urls 请求,这些请求将在meta 中包含extra 数据,您以后可以使用这些数据保存在不同的文件中。
在parse() 中,您必须从meta 获取此extra 并添加到item。
在管道导出器中,您必须从 item 获取 extra 并打开不同的文件。
import scrapy
from os import listdir
from os.path import isfile, join
import json
class HotelInfoSpider(scrapy.Spider):
name = 'hotel_info'
allowed_domains = ['lastsecond.ir']
def start_requests(self):
# get start urls from links list of every file
files = [f for f in listdir('lastsecond/hotels/') if isfile(join('lastsecond/hotels/', f))]
for i, filename in enumerate(files):
with open('lastsecond/hotels/' + filename) as f:
data = json.load(f)
links = data["links"]
for url in links:
yield scrapy.Request(url, meta={'extra': i})
def parse(self, response):
print('url:', response.url)
extra = response.meta['extra']
print('extra:', extra)
yield {'url': response.url, 'extra': extra, 'other': ...}
管道.py
class MyExportPipeline(object):
def process_item(self, item, spider):
# get extra and use it in filename
filename = 'result{}.csv'.format(item['extra'])
# open file for appending
with open(filename, 'a') as f:
writer = csv.writer(f)
# write only selected elements - skip `extra`
row = [item['url'], item['other']
writer.writerow(row)
return item
settings.py
ITEM_PIPELINES = {
'your_porject_name.pipelines.MyExportPipeline': 300,
}