2016-07-02 1 views
0

こんにちはStackOverflowのコミュニティScrapy - 動的allowed_urlsために追加することでSTART_URIリダイレクトを克服 - parse_start_url問題

私は次のような問題があります。

を、私はウェブサイトの長いリストをクロールしようとしています。 start_urlリストのウェブサイトの一部がリダイレクトします(301)。私は、リダイレクトされたWebサイトをstart_urlリストからクロールして、あたかもそれがallowed_domainリストにあるかのようにしたいと思います。たとえば、example.comは私のstart_urlリストにあり、ドメインリストは許可されていて、example.comはfoo.comにリダイレクトされています。私はfoo.comをクロールしたい。

DEBUG: Redirecting (301) to <GET http://www.foo.com/> from <GET http://www.example.com> 

IはOffsiteMiddlewareを変更することによって解決策を提供する次の応答Scrapy Crawl all websites in start_url even if redirect に気づきました。その部分は分かりますが、parse_start_urlがどのようにオーバーライドされているかはわかりません。

import scrapy 
import urllib.request 
import urllib.parse 
import json 
from placementarchitect import bingapi 
import tldextract 

from spiderproject.items import DmozItem 
from scrapy.crawler import CrawlerProcess 

class GoodSpider(scrapy.Spider): 
    name = "goodoldSpider" 

    def __init__(self, input=None): 
     self.searchterm = input 
     self.urlstocrawl = bingapi.get_crawl_urls(self.searchterm) # This returns a list of crawlable sites from the BingSearchAPI 
     self.start_urls = self.urlstocrawl 
     self.allowed_domains = [] 

    def parse_start_url(self, response): 
     domain = tldextract.extract(str(response.request.url)).registered_domain 
     if domain not in self.allowed_domains: 
      self.allowed_domains.append(domain) 
     else: 
      return self.parse(response) 

    def parse(self, response): 
     for href in response.xpath("//a/@href"): 
      url = response.urljoin(href.extract()) 
      yield scrapy.Request(url, callback=self.parse_dir_contents) 

    def parse_dir_contents(self, response): 
     for sel in response.xpath('//div[attribute::class="cat-item"]'): 
      item = DmozItem() 
      item['title'] = sel.xpath('a/div/text()').extract() 
      item['link'] = sel.xpath('a/@href').extract() 
      item['desc'] = sel.xpath('text()').extract() 
      yield item 

     next_page = response.css(".cat-item>a::attr('href')") 
     if next_page: 
      url = response.urljoin(next_page[0].extract()) 
      yield scrapy.Request(url, self.parse_dir_contents) 

process = CrawlerProcess({ 
    'USER_AGENT': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)' 
}) 

process.crawl(GoodSpider, input='"good news"')     
process.start() # the script will block here until the crawling is finished 

scrapyのドキュメントがparse_start_urlにまばらであるので、私はこれが実装されるかわからない:これは、これまでの私のコードです。そのような私のソリューションは動作していないようです。

私はこれが原因

def parse_start_url() 

がどのように実装されるかにあるかと思います。

アドバイスをいただければ幸いです。

マイク

+0

は解決策ではありませんallowed_domains' '取り除きますか? – eLRuLL

答えて

0

私はそれを理解しました。それは持っているし、実際に必要はありませんでした。その代わり

def parse_start_url(...) 

を、私はに私が以前にデフparse_start_url(...)の下に持っていたコードを統合クモのメインDEF機能解析:

import scrapy 
import urllib.request 
import urllib.parse 
import json 
from placementarchitect import bingapi 
import tldextract 

from spiderproject.items import DmozItem 
from scrapy.crawler import CrawlerProcess 

class GoodSpider(scrapy.Spider): 
name = "goodoldSpider" 

def __init__(self, input=None): 
    self.searchterm = input 
    self.urlstocrawl = bingapi.get_crawl_urls(self.searchterm) # This returns a list of crawlable sites from the BingSearchAPI 
    self.start_urls = self.urlstocrawl 
    self.allowed_domains = [] 

    print("TEST >>> In Searchscraper.py: " + str(self.urlstocrawl)) 

## Commented this part out as it is not required anymore - code was integrated into def parse(..) below 
# def parse_start_url(self, response): 
#  domain = tldextract.extract(str(response.request.url)).registered_domain 
#  print(domain) 
#  if domain not in self.allowed_domains: 
#   self.allowed_domains.append(domain) 
#  return self.parse(response.url, callback=self.parse) 

def parse(self, response): 
    domain = tldextract.extract(str(response.request.url)).registered_domain 
    print(domain) 
    if domain not in self.allowed_domains: 
     self.allowed_domains.append(domain) 
    for href in response.xpath("//a/@href"): 
     url = response.urljoin(href.extract()) 
     yield scrapy.Request(url, callback=self.parse_dir_contents) 

def parse_dir_contents(self, response): 
    for sel in response.xpath('//div[attribute::class="cat-item"]'): 
     item = DmozItem() 
     item['title'] = sel.xpath('a/div/text()').extract() 
     item['link'] = sel.xpath('a/@href').extract() 
     item['desc'] = sel.xpath('text()').extract() 
     yield item 

    next_page = response.css(".cat-item>a::attr('href')") 
    if next_page: 
     url = response.urljoin(next_page[0].extract()) 
     yield scrapy.Request(url, self.parse_dir_contents) 

process = CrawlerProcess({ 
    'USER_AGENT': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)' 
}) 

process.crawl(GoodSpider, input='"good news"') 
process.start() # the script will block here until the crawling is finished 

このソリューションは、最初のstart_urlがallowed_domainsリストにリダイレクトするドメインを動的に追加します。

これは、次のように他のすべてのドメインがフィルタリングされることを意味します:

[scrapy] DEBUG: Filtered offsite request to 'www.pinterest.com': <GET http://www.pinterest.com/goodnewsnetwork/> 
関連する問題