2017-08-25 5 views
4

私は部分的に取り組んでいる次のコードを持って、Scrapy CrawlSpider + Splash:linkextractorでリンクをたどる方法は?

class ThreadSpider(CrawlSpider): 
    name = 'thread' 
    allowed_domains = ['bbs.example.com'] 
    start_urls = ['http://bbs.example.com/diy'] 

    rules = (
     Rule(LinkExtractor(
      allow=(), 
      restrict_xpaths=("//a[contains(text(), 'Next Page')]") 
     ), 
      callback='parse_item', 
      process_request='start_requests', 
      follow=True), 
    ) 

def start_requests(self): 
    for url in self.start_urls: 
     yield SplashRequest(url, self.parse_item, args={'wait': 0.5}) 

def parse_item(self, response): 
    # item parser 

コードは、start_urlsのために実行されますが、私はルールでstart_requests()方法とラインprocess_request='start_requests',をコメントアウトした場合、restricted_xpathsに指定されたリンクをたどるません。それはもちろん、jsレンダリングなしで、意図したところでリンクを実行して追跡します。

私は2つの関連する質問、start_requests()方法でSplashRequest()scrapy.Request()を変えCrawlSpider with Splash getting stuck after first URLCrawlSpider with Splash、具体的に読んでいるが、それは動作するようには思えません。私のコードで何が間違っていますか? おかげで、

答えて

0
コードの下

使用して - ちょうどコピーして

restrict_xpaths=('//a[contains(text(), "Next Page")]') 

代わりの

restrict_xpaths=("//a[contains(text(), 'Next Page')]") 
+0

これは役に立たないようです。もし 'start_requests()'をコメントアウトすると 'restrict_xpaths =(" // a [contains(text()、 'Next Page')] ")'という行がうまく動作することを覚えておいてください。どのように私はこれは多くのユーザーがここに報告された未解決の問題であることを認識しています:https://github.com/scrapy-plugins/scrapy-splash/issues/92 –

0

を貼り付ける私はScrapy CrawlSpiderでスプラッシュを統合すると、特定のように見えた同様の問題を持っていました。開始URLだけを訪問して終了します。私がそれを稼働させるために管理した唯一の方法は、scrapy-splashプラグインを使用せず、代わりに 'process_links'メソッドを使用して、スプラッシュhttp api urlをscrapyが収集するすべてのリンクにプリペンドすることでした。そして、私はこの方法から生ずる新しい問題を補うために他の調整を行った。ここに私がしたことがあります:

あなたはどこかに格納するつもりならば、これらの2つのツールを一緒にスプラッシュURLを入れて、それを分解する必要があります。すべてのリンクにpreppendedされたスプラッシュのURLで

from urllib.parse import urlencode, parse_qs 

、scrapyは「オフサイトのドメイン要求」としてそれらをすべて除外しますので、我々は「localhost」の許可されたドメインを作成します。

allowed_domains = ['localhost'] 
start_urls = ['https://www.example.com/'] 

その後、我々は唯一のサイトをクロールする際に延々とウェブをクロールしてしまうことがあるのでしかし、これが問題となります。これをLinkExtractorルールで修正しましょう。必要なドメインからのリンクのみを掻き集めることで、オフサイトリクエストの問題が回避されます。

LinkExtractor(allow=r'(http(s)?://)?(.*\.)?{}.*'.format(r'example.com')), 
process_links='process_links', 

ここにprocess_linksメソッドがあります。 urlencodeメソッドの辞書は、すべてのスプラッシュ引数を置く場所です。最後に

def process_links(self, links): 
    for link in links: 
     if "http://localhost:8050/render.html?&" not in link.url: 
      link.url = "http://localhost:8050/render.html?&" + urlencode({'url':link.url, 
                      'wait':2.0}) 
    return links 

、parse_qsメソッドを使用して、スプラッシュURLからバックURLを取ります。

parse_qs(response.url)['url'][0] 

このアプローチに関する最後の注意点の1つです。冒頭のスプラッシュURLに「&」があることがわかります。 (... render.html?&)。これにより、urlencodeメソッドを使用しているときに引数がどのような順序であっても、実際のURLを一貫して取り出すためのスプラッシュURLの解析が行われます。

関連する問題