Ищу помощь для улучшения искателя

#python #python-2.7 #web-scraping #scrapy

#python #python-2.7 #очистка веб-страниц #scrapy

Вопрос:

Я новичок в Scrapy / Python, я разработал сканер, который может находить домены с истекшим сроком действия и сканировать каждый в SEO API.
Мой сканер работает нормально, но я уверен, что он не на 100% оптимизирован для этой работы.

Возможно ли, чтобы были какие-то хитрости для улучшения сканера, пожалуйста?

expired.py :

 class HttpbinSpider(CrawlSpider):
    name = "expired"

    rules = (
        Rule(LxmlLinkExtractor(allow=('.com', '.fr', '.net', '.org', '.info', '.casino', '.eu'),
                               deny=('facebook', 'amazon', 'wordpress', 'blogspot', 'free', 'reddit'),
             callback='parse_obj',
             process_request='add_errback',
             follow=True),
    )

    def __init__(self, domains=None, **kwargs):
        self.start_urls = json.loads(domains)
        super(HttpbinSpider, self).__init__()

    def add_errback(self, request):
        return request.replace(errback=self.errback_httpbin)

    def errback_httpbin(self, failure):
        if failure.check(DNSLookupError):
            request = failure.request
            ext = tldextract.extract(request.url)
            domain = ext.registered_domain
            if domain != '':
                domain = domain.replace(" ", "")
                self.check_domain(domain)

    def check_domain(self, domain):
        if self.is_available(domain) == 'AVAILABLE':

            self.logger.info('## Domain Expired : %s', domain)

            url = 'http://api.majestic.com/api/json?app_api_key=APIamp;cmd=GetIndexItemInfoamp;items=1amp;item0='   domain   'amp;datasource=fresh'
            response = urllib.urlopen(url)
            data = json.loads(response.read())
            response.close()

            TrustFlow = data['DataTables']['Results']['Data'][0]['TrustFlow']
            CitationFlow = data['DataTables']['Results']['Data'][0]['CitationFlow']
            RefDomains = data['DataTables']['Results']['Data'][0]['RefDomains']
            ExtBackLinks = data['DataTables']['Results']['Data'][0]['ExtBackLinks']

            if (RefDomains > 20) and (TrustFlow > 4) and (CitationFlow > 4):
                insert_table(domain, TrustFlow, CitationFlow, RefDomains, ExtBackLinks)

    def is_available(self, domain):
        url = 'https://api.internet.bs/Domain/Check?ApiKey=KEYamp;Password=PSWDamp;responseformat=jsonamp;domain'   domain
        response = urllib.urlopen(url)
        data = json.loads(response.read())
        response.close()
        return data['status']
  

Большое спасибо.

Ответ №1:

Самая большая проблема в вашем коде — это запросы urllib, которые блокируют всю процедуру async scrapy. Вы можете легко заменить их цепочкой запросов scrapy, выдав a scrapy.Request .

Что-то вроде этого:

 def errback_httpbin(self, failure):
    if not failure.check(DNSLookupError):
        return
    request = failure.request
    ext = tldextract.extract(request.url)
    domain = ext.registered_domain
    if domain == '':
        logging.debug('no domain: {}'.format(request.url))
        return
    domain = domain.replace(" ", "")
    url = 'https://api.internet.bs/Domain/Check?ApiKey=KEYamp;Password=PSWDamp;responseformat=jsonamp;domain='   domain
    return Request(url, self.parse_checkdomain)

def parse_checkdomain(self, response):
    """check whether domain is available"""
    data = json.loads(response.read())
    if data['status'] == 'AVAILABLE':
        self.logger.info('Domain Expired : {}'.format(data['domain']))
        url = 'http://api.majestic.com/api/json?app_api_key=APIamp;cmd=GetIndexItemInfoamp;items=1amp;item0='   data['domain']  'amp;datasource=fresh'
        return Request(url, self.parse_claim)

def parse_claim(self, response):
    """save available domain's details"""
    data = json.loads(response.read())
    # eliminate redundancy
    results = data['DataTables']['Results']['Data'][0]
    # snake case is more pythonic
    trust_flow = results['TrustFlow']
    citation_flow = results['CitationFlow']
    ref_domains = results['RefDomains']
    ext_back_links = results['ExtBackLinks']

    # don't need to wrap everything in ()
    if ref_domains > 20 and trust_flow > 4 and citation_flow > 4:
        insert_table(domain, trust_flow, citation_flow, ref_domains, ext_back_links)
  

Таким образом, ваш код не блокируется и является полностью асинхронным. Как правило, вы не хотите использовать ничего, кроме запросов scrapy, при работе с http в вашем scrapy spider.

Комментарии:

1. Большое спасибо за вашу помощь и улучшение кода. Я попробую это!

2. Я использую BloomFilter, и у меня много ошибок в журналах raise IndexError("BloomFilter is at capacity") . Вы знаете, почему?

3. @Pixel извините, я не совсем знаком с этим. AFAIK согласно pybloom wiki, он должен открыть новый более крупный экземпляр. Вы можете попробовать указать емкость при создании фильтра. Я не думаю, что это связано с scrapy, и вы, вероятно, захотите открыть для этого новый вопрос 🙂

4. @Pixel извините, я не в skype, но если у вас есть какие-либо вопросы, вы можете найти меня на #python, как tinarg на irc.freenode.org