Python 基于Scrapy爬行蜘蛛的起始URL的动态规则?

Python 基于Scrapy爬行蜘蛛的起始URL的动态规则?,python,web-scraping,scrapy,web-crawler,scrapy-spider,Python,Web Scraping,Scrapy,Web Crawler,Scrapy Spider,我正在写一个Scrapy scraper,它使用CrawlSpider来抓取站点,检查它们的内部链接,并抓取任何外部链接的内容(与原始域不同的域的链接) 我用两条规则做到了这一点,但它们是基于被爬网站点的域。如果我想在多个网站上运行这个,我会遇到一个问题,因为我不知道我当前使用的是哪个“开始url”,所以我无法适当地更改规则 以下是我到目前为止的想法,它适用于一个网站,我不知道如何将其应用于一系列网站: 类主页蜘蛛(爬行蜘蛛): 名称='主页' 主页http://www.somesite.com

我正在写一个Scrapy scraper,它使用CrawlSpider来抓取站点,检查它们的内部链接,并抓取任何外部链接的内容(与原始域不同的域的链接)

我用两条规则做到了这一点,但它们是基于被爬网站点的域。如果我想在多个网站上运行这个,我会遇到一个问题,因为我不知道我当前使用的是哪个“开始url”,所以我无法适当地更改规则

以下是我到目前为止的想法,它适用于一个网站,我不知道如何将其应用于一系列网站:

类主页蜘蛛(爬行蜘蛛):
名称='主页'
主页http://www.somesite.com'
start_url=[主页]
#剥离http和www
domain=homepage.replace('http://','').replace('https://','').replace('www.','')
域=域[:-1]如果域[-1]=='/'其他域
规则=(
规则(LinkExtractor(允许_域=(域),拒绝_域=()),callback='parse_internal',follow=True),
规则(LinkExtractor(允许_域=(),拒绝_域=(域)),callback='parse_external',follow=False),
)
def parse_内部(自我,响应):
#日志内部页面。。。
def parse_外部(自身、响应):
#解析外部页面。。。
这可能是通过在调用scraper时将start_url作为参数传递来实现的,但是我正在寻找一种在scraper本身中以编程方式实现这一点的方法

有什么想法吗? 谢谢


Simon.

开始\u URL
中迭代所有网站链接,并填充
允许的\u域
拒绝\u域
数组。然后定义规则

start_urls = ["www.website1.com", "www.website2.com", "www.website3.com", "www.website4.com"]

allow_domains = []
deny_domains = []

for link in start_urls

    # strip http and www
    domain = link.replace('http://', '').replace('https://', '').replace('www.', '')
    domain = domain[:-1] if domain[-1] == '/' else domain

    allow_domains.extend([domain])
    deny_domains.extend([domain])


rules = (
    Rule(LinkExtractor(allow_domains=allow_domains, deny_domains=()), callback='parse_internal', follow=True),
    Rule(LinkExtractor(allow_domains=(), deny_domains=deny_domains), callback='parse_external', follow=False),
)

迭代
开始\u URL
中的所有网站链接,并填充
允许的\u域
拒绝\u域
数组。然后定义规则

start_urls = ["www.website1.com", "www.website2.com", "www.website3.com", "www.website4.com"]

allow_domains = []
deny_domains = []

for link in start_urls

    # strip http and www
    domain = link.replace('http://', '').replace('https://', '').replace('www.', '')
    domain = domain[:-1] if domain[-1] == '/' else domain

    allow_domains.extend([domain])
    deny_domains.extend([domain])


rules = (
    Rule(LinkExtractor(allow_domains=allow_domains, deny_domains=()), callback='parse_internal', follow=True),
    Rule(LinkExtractor(allow_domains=(), deny_domains=deny_domains), callback='parse_external', follow=False),
)
我已经找到了一个解决方案,并使用了公认答案中提供的第二个选项来开发此问题的解决方案,因为它在scrapy中不受开箱即用的支持

我创建了一个函数,该函数获取url作为输入,并为其创建规则:

def rules_for_url(self,url):
域=工具。获取域(url)
规则=(
规则(LinkExtractor(允许_域=(域),拒绝_域=()),callback='parse_internal',follow=True),
规则(LinkExtractor(允许_域=(),拒绝_域=(域)),callback='parse_external',follow=False),
)
返回规则
然后我重写了爬行蜘蛛的一些函数

  • 我将_规则更改为一个字典,其中键是不同的网站域,值是该域的规则(使用rules_for _url)。规则的填充在
    \u compile\u rules

  • 然后,我在
    \u请求\u遵循
    \u响应\u下载
    中进行适当更改,以支持使用
    \u规则
    的新方法

  • \u规则={}
    def_请求_遵循(自我、响应):
    如果不存在(响应、HtmlResponse):
    回来
    seen=set()
    domain=Tools.get\u域(response.url)
    对于n,枚举中的规则(self.\u规则[域]):
    links=[lnk代表规则中的lnk.link\u提取器.extract\u links(响应)
    如果lnk未被发现]
    如果链接和rule.process\u链接:
    链接=规则。处理链接(链接)
    对于链接中的链接:
    seen.add(链接)
    r=self.\u构建请求(域+';'+str(n),链接)
    让步规则。处理请求(r)
    def_响应_下载(自我,响应):
    meta_rule=response.meta['rule'].split(';'))
    域=元规则[0]
    规则n=int(元规则[1])
    规则=自我。规则[域][规则]
    返回self.\u parse\u response(response,rule.callback,rule.cb\u kwargs,rule.follow)
    定义编译规则(自):
    def get_方法(方法):
    如果可调用(方法):
    返回方法
    elif isinstance(方法,六种字符串类型):
    返回getattr(self、method、None)
    对于self.start\u url中的url:
    url\u rules=self.rules\u for\u url(url)
    域=工具。获取域(url)
    self.\u规则[domain]=[url\u规则中r的copy.copy(r)]
    对于self中的规则。\u规则[域]:
    rule.callback=get_方法(rule.callback)
    rule.process\u links=获取方法(rule.process\u links)
    rule.process\u request=获取方法(rule.process\u request)
    
    请参阅原始函数

    现在,爬行器将简单地遍历start_url中的每个url,并为该url创建一组特定的规则。然后对每个正在爬网的网站使用适当的规则

    希望这能帮助将来偶然发现这个问题的人

    Simon。

    我找到了一个解决方案,并使用了公认答案中提供的第二个选项来开发此问题的解决方案,因为它在scrapy中不受开箱即用的支持

    我创建了一个函数,该函数获取url作为输入,并为其创建规则:

    def rules_for_url(self,url):
    域=工具。获取域(url)
    规则=(
    规则(LinkExtractor(允许_域=(域),拒绝_域=()),callback='parse_internal',follow=True),
    规则(LinkExtractor(允许_域=(),拒绝_域=(域)),callback='parse_external',follow=False),
    )
    返回规则
    
    然后我重写了爬行蜘蛛的一些函数

  • 我将_规则更改为一个字典,其中键是不同的网站域,值是该域的规则(使用rules_for _url)。规则的填充在
    \u compile\u rules

  • 然后,我在
    \u请求\u遵循
    \u响应\u下载
    中进行适当更改,以支持使用
    \u规则
    的新方法

  • \u规则={}
    def_请求_遵循(自我、响应):
    如果不存在(响应、HtmlResponse):
    回来
    seen=set()
    多马