Python 如何从URL域调用正确的类

Python 如何从URL域调用正确的类,python,python-3.x,class-variables,Python,Python 3.x,Class Variables,我目前正在创建一个web爬虫程序,我想在其中调用正确的类来从给定的URL抓取web元素 目前,我已创建: import sys import tldextract import requests class Scraper: scrapers = {} def __init_subclass__(scraper_class): Scraper.scrapers[scraper_class.url] = scraper_class @classmet

我目前正在创建一个web爬虫程序,我想在其中调用正确的类来从给定的URL抓取web元素

目前,我已创建:

import sys
import tldextract
import requests


class Scraper:
    scrapers = {}

    def __init_subclass__(scraper_class):
        Scraper.scrapers[scraper_class.url] = scraper_class

    @classmethod
    def for_url(cls, url):
        k = tldextract.extract(url)
        # return Scraper.scrapers[k.domain]()
        # or
        return cls.scrapers[k.domain]()


class BBCScraper(Scraper):
    url = 'bbc.co.uk'

    def scrape(s):
        print(s)
        # FIXME Scrape the correct values for BBC
        return "Scraped BBC News"


url = 'https://www.bbc.co.uk/'
scraper = Scraper.for_url(url)
scraper.scrape(requests.get(url))
我现在想做的是,如果BBC是域名,那么它应该进入
类BBCScraper(Scraper):
,因为我们称之为
Scraper.scrape(requests.get(url))
它应该在
BBCScraper->scrape->Return web元素中刮取web元素

但是,我在尝试运行它输出的脚本时遇到问题:

Outprint >>> return cls.scrapers[k.domain]() KeyError: 'bbc'

我想知道如何根据已给
for_url
classmethod

的域调用正确的类,问题是
k.domain
返回
bbc
,而您编写了
url='bbc.co.uk'
,所以有一个解决方案

  • 使用
    url='bbc.co.uk'
    k.registered\u域
  • 使用
    url='bbc'
    k.domain
并在
scrape
方法中添加一个参数以获得响应

来自abc导入抽象方法的

导入请求
进口tldextract
类别刮刀:
刮刀={}
定义初始子类(刮刀类):
Scraper.scrapers[Scraper\u class.url]=Scraper\u类
@类方法
url(cls,url)的定义:
k=tldextract.extract(url)
返回cls.scrapers[k.registered_domain]()
@抽象方法
def刮取(自我,内容:requests.Response):
通过
BBCScraper级(刮刀):
url='bbc.co.uk'
def刮取(自我,内容:requests.Response):
返回“英国广播公司新闻”
如果名称=“\uuuuu main\uuuuuuuu”:
url='1〕https://www.bbc.co.uk/'
scraper=scraper.for_url(url)
r=scraper.scrape(requests.get(url))
印刷品(右)#英国广播公司新闻

改善 我建议将
url
存储在一个属性中,以放置
请求。在
scrape
中获取
,这样主目录中的代码就更少了

类刮刀:
刮刀={}
定义初始子类(刮刀类):
Scraper.scrapers[Scraper\u class.domain]=Scraper\u类
@类方法
url(cls,url)的定义:
k=tldextract.extract(url)
返回cls.scrapers[k.registered_domain](url)
@抽象方法
def刮除(自):
通过
BBCScraper级(刮刀):
域名='bbc.co.uk'
定义初始化(self,url):
self.url=url
def刮除(自):
rep=requests.Response=requests.get(self.url)
content=rep.text#所有HTML内容
返回“刮BBC新闻”+内容[:20]
如果名称=“\uuuuu main\uuuuuuuu”:
url='1〕https://www.bbc.co.uk/'
scraper=scraper.for_url(url)
r=刮刀。刮刀()

印刷品(右)#刮掉了BBC新闻-阿兹罗!它似乎可以工作,但我确实在
Scraper.scrapers[Scraper\u class.domain]=Scraper\u class
上收到了一个警告,上面写着类“Scraper”的
未解析属性引用“domain”
-它应该这么说吗?@gragraptornewbie你是否改为
domain='bbc.co.uk'
,我所做的只是复制粘贴您回答的第二个代码
Improve
:D