2015-08-21 3 views
3

Паук для справки:Как Scrapy сделку с Javascript

import scrapy 
from scrapy.spiders import Spider 
from scrapy.selector import Selector 
from script.items import ScriptItem 



    class RunSpider(scrapy.Spider): 
     name = "run" 
     allowed_domains = ["stopitrightnow.com"] 
     start_urls = (
      'http://www.stopitrightnow.com/', 
     ) 



     def parse(self, response): 


      for widget in response.xpath('//div[@class="shopthepost-widget"]'): 
       #print widget.extract() 
       item = ScriptItem() 
       item['url'] = widget.xpath('.//a/@href').extract() 
       url = item['url'] 
       #print url 
       yield item 

Когда я запускаю этот вывод в терминале следующим образом:

2015-08-21 14:23:51 [scrapy] DEBUG: Scraped from <200 http://www.stopitrightnow.com/> 
{'url': []} 
<div class="shopthepost-widget" data-widget-id="708473"> 
<script type="text/javascript">!function(d,s,id){var e, p = /^http:/.test(d.location) ? 'http' : 'https';if(!d.getElementById(id)) {e = d.createElement(s);e.id = id;e.src = p + '://' + 'widgets.rewardstyle.com' + '/js/shopthepost.js';d.body.appendChild(e);}if(typeof window.__stp === 'object') if(d.readyState === 'complete') {window.__stp.init();}}(document, 'script', 'shopthepost-script');</script><br> 

Это HTML:

<div class="shopthepost-widget" data-widget-id="708473" data-widget-uid="1"><div id="stp-55d44feabd0eb" class="stp-outer stp-no-controls"> 
    <a class="stp-control stp-left stp-hidden">&lt;</a> 
    <div class="stp-inner" style="width: auto"> 
     <div class="stp-slide" style="left: -0%"> 
         <a href="http://rstyle.me/iA-n/zzhv34c_" target="_blank" rel="nofollow" class="stp-product " data-index="0" style="margin: 0 0px 0 0px"> 
       <span class="stp-help"></span> 
       <img src="//images.rewardstyle.com/img?v=2.13&amp;p=n_24878713"> 
          </a> 
         <a href="http://rstyle.me/iA-n/zzhvw4c_" target="_blank" rel="nofollow" class="stp-product " data-index="1" style="margin: 0 0px 0 0px"> 
       <span class="stp-help"></span> 
       <img src="//images.rewardstyle.com/img?v=2.13&amp;p=n_24878708"> 

Мне кажется, что он поражает блок при попытке активировать Javascript. Я знаю, что javascript не может работать в режиме scrapy, но должен быть способ добраться до этих ссылок. Я посмотрел на селен, но не могу понять.

Любая помощь приветствуется.

ответ

5

Я решил это с помощью ScrapyJS.

Следуйте инструкциям по установке в официальной документации и this answer.

Вот тест паука я использовал:

# -*- coding: utf-8 -*- 
import scrapy 


class TestSpider(scrapy.Spider): 
    name = "run" 
    allowed_domains = ["stopitrightnow.com"] 
    start_urls = (
     'http://www.stopitrightnow.com/', 
    ) 

    def start_requests(self): 
     for url in self.start_urls: 
      yield scrapy.Request(url, meta={ 
       'splash': { 
        'endpoint': 'render.html', 
        'args': {'wait': 0.5} 
       } 
      }) 

    def parse(self, response): 
     for widget in response.xpath('//div[@class="shopthepost-widget"]'): 
      print widget.xpath('.//a/@href').extract() 

И вот что у меня есть на консоли:

[u'http://rstyle.me/iA-n/7bk8r4c_', u'http://rstyle.me/iA-n/7bk754c_', u'http://rstyle.me/iA-n/6th5d4c_', u'http://rstyle.me/iA-n/7bm3s4c_', u'http://rstyle.me/iA-n/2xeat4c_', u'http://rstyle.me/iA-n/7bi7f4c_', u'http://rstyle.me/iA-n/66abw4c_', u'http://rstyle.me/iA-n/7bm4j4c_'] 
[u'http://rstyle.me/iA-n/zzhv34c_', u'http://rstyle.me/iA-n/zzhvw4c_', u'http://rstyle.me/iA-n/zwuvk4c_', u'http://rstyle.me/iA-n/zzhvr4c_', u'http://rstyle.me/iA-n/zzh9g4c_', u'http://rstyle.me/iA-n/zzhz54c_', u'http://rstyle.me/iA-n/zwuuy4c_', u'http://rstyle.me/iA-n/zzhx94c_'] 
+0

Это фантастика, однако она просто вешает консоль в течение многих лет: 2015-08-21 16:36:14 [scrapy] INFO: Просканировано 0 страниц (на 0 страницах/мин), соскоблило 0 предметов (на 0 пунктов/мин) 2015-08-21 16:37:00 [scrapy] DEBUG: повторил попытку (не удалось 3 раза): время соединения по протоколу TCP out: 60: Время работы отключено. 2015-08-21 16:37:00 [scrapy] ОШИБКА: Ошибка при загрузке : время соединения по протоколу TCP: 60: время ожидания работы. –

+0

@ Wine.Merchant, вы запустили контейнер докер-брызг? Благодарю. – alecxe

+0

Я открыл докер и положил нужную строку $ docker run -p 8050: 8050 scrapinghub/splash, а затем это событие 2015-08-21 15: 22: 19.651375 [-] Запуск фабрики

5

Не-Javascript альтернатива Alecxe является инспектировать где страница загружает содержимое вручную и добавляет его функционально (see this SO question for more details).

В этом случае мы получаем следующее: Network traffic

Так, <div class="shopthepost-widget" data-widget-id="708473">, Javascript выполняется встраивать URL "widgets.rewardstyle.com/stps/ .html".

Вы могли бы справиться с этим самостоятельно, вручную формирует запрос для этих URL-адресов сами:

def parse(self, response): 
    for widget in response.xpath('//div[@class="shopthepost-widget"]'): 
     widget_id = widget.xpath('@data-widget-id').extract()[0] 
     widget_url = "http://widgets.rewardstyle.com/stps/{id}.html".format(id=widget_id) 
     yield Request(widget_url, callback=self.parse_widget) 

def parse_widget(self, response): 
    for link in response.xpath('//a[contains(@class, "stp-product")]'): 
     item = JavasItem() # Name provided by author, see comments below 
     item['link'] = links.xpath("@href").extract() 
     yield item 

    # Do whatever else you want with the opened page. 

Если вам нужно сохранить эти виджеты, связанные с тем, что после/статьи они являются частью, передать эту информацию в запрос через meta.

EDIT:parse_widget() был обновлен. Он использует contains для определения класса, так как он имеет место в конце. Вы также можете использовать селектор CSS, но это действительно ваш вызов.

+0

Да, это хороший вариант без сделки с js! – alecxe

+0

Кажется, что это было бы более приятным решением, без необходимости полагаться на третью сторону. Терминал говорит, что он переходит на исходную страницу виджета, но я все еще не могу хранить элементы на странице. Не могли бы вы привести пример того, как вы получите ссылки для сохранения с помощью parse_widget? –

+0

Я использую это. или Сель в response.xpath ('// а [@ класс = "СТП-контроль СТП левый СТП-скрытый"]'): \t \t пункт = JavasItem() \t \t пункт [ 'itemUrl'] = ответ .xpath ('.// ​​a/@ href'). extract() \t \t item item –

Смежные вопросы