Django集成Scrapy报错:TypeError: RepoSpider.start_requests()缺少必填参数url
解决TypeError: RepoSpider.start_requests() missing 1 required positional argument: 'url'
错误原因
你重写的start_requests方法额外添加了url参数,但Scrapy框架调用该方法时不会传入此参数;而你通过process.crawl(RepoSpider, url)传递的参数是用于初始化Spider实例的,并非直接传给start_requests,这就导致了参数缺失的报错。
同时你的代码存在一个逻辑错误:GitHub仓库URL的结构为https://github.com/<username>/<repo>,原代码中通过url.split('/')获取username和repo的顺序写反了,会导致数据存储错误,下面的修复方案会一并修正这个问题。
修复方案一:通过Spider初始化方法接收URL
修改Spider类,添加__init__方法接收传入的URL并存储为实例变量,再在start_requests中使用该变量:
import scrapy from App.models import Repo class RepoSpider(scrapy.Spider): name = "RepoSpider" allowed_domains = ["github.com"] def __init__(self, url=None, *args, **kwargs): super().__init__(*args, **kwargs) self.target_url = url def start_requests(self): if self.target_url: yield scrapy.Request(self.target_url) def parse(self, response): url = response.url url_parts = url.split('/') # 修正username和repo的获取顺序 username = url_parts[-2] repo = url_parts[-1] description = response.css('.f4.my-3::text').get(default='').strip() language = response.css('.color-fg-default.text-bold.mr-1::text').get(default='') stars = response.css('a.Link.Link--muted strong::text').get(default='0').strip() yield { 'username': username, 'repo': repo, 'description': description, 'top_language': language, 'stars': stars } scraped_repo = Repo( url=url, username=username, description=description, top_language=language, stars=stars ) scraped_repo.save()
修复方案二:利用Scrapy默认的start_urls属性
不重写start_requests方法,直接在初始化时将传入的URL赋值给start_urls,更符合Scrapy的原生逻辑:
import scrapy from App.models import Repo class RepoSpider(scrapy.Spider): name = "RepoSpider" allowed_domains = ["github.com"] def __init__(self, url=None, *args, **kwargs): super().__init__(*args, **kwargs) if url: self.start_urls = [url] def parse(self, response): url = response.url url_parts = url.split('/') # 修正username和repo的获取顺序 username = url_parts[-2] repo = url_parts[-1] description = response.css('.f4.my-3::text').get(default='').strip() language = response.css('.color-fg-default.text-bold.mr-1::text').get(default='') stars = response.css('a.Link.Link--muted strong::text').get(default='0').strip() yield { 'username': username, 'repo': repo, 'description': description, 'top_language': language, 'stars': stars } scraped_repo = Repo( url=url, username=username, description=description, top_language=language, stars=stars ) scraped_repo.save()
说明
你的Django视图代码无需修改,process.crawl(RepoSpider, url)已经正确将URL参数传递给Spider的初始化方法。
内容的提问来源于stack exchange,提问作者Abdulhamid Usman
相关产品推荐
相关产品推荐

