2012-05-18 4 views
6

Я откладываю сайт с использованием рамки scrapy и не могу нажать на ссылку javascript для открытия другой страницы.Выполнение Javascript Функции отправки формы с использованием scrapy в python

я могу определить код на странице, как:

<a class="Page" alt="Click to view job description" title="Click to view job description" href="javascript:sysSubmitForm('frmSR1');">Accountant&nbsp;</a> 

может предложить любой из меня, как выполнить этот JavaScript в scaroy и получить другую страницу через я могу получить данные из этой страницы.

Заранее спасибо

ответ

8

Оформить заказ ниже, как использовать скрипит с селеном. Сканирование будет медленнее, так как вы не просто загружаете html, но получаете полный доступ к DOM.

Примечание: У меня есть копия этого фрагмента, поскольку ранее предоставленные ссылки больше не работают.

# Snippet imported from snippets.scrapy.org (which no longer works) 

from scrapy.contrib.spiders import CrawlSpider, Rule 
from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor 
from scrapy.selector import HtmlXPathSelector 
from scrapy.http import Request 

from selenium import selenium 

class SeleniumSpider(CrawlSpider): 
    name = "SeleniumSpider" 
    start_urls = ["http://www.domain.com"] 

    rules = (
     Rule(SgmlLinkExtractor(allow=('\.html',)), 
     callback='parse_page',follow=True), 
    ) 

    def __init__(self): 
     CrawlSpider.__init__(self) 
     self.verificationErrors = [] 
     self.selenium = selenium("localhost", 4444, "*chrome", "http://www.domain.com") 
     self.selenium.start() 

    def __del__(self): 
     self.selenium.stop() 
     print self.verificationErrors 
     CrawlSpider.__del__(self) 

    def parse_page(self, response): 
     item = Item() 

     hxs = HtmlXPathSelector(response) 
     #Do some XPath selection with Scrapy 
     hxs.select('//div').extract() 

     sel = self.selenium 
     sel.open(response.url) 

     #Wait for javscript to load in Selenium 
     time.sleep(2.5) 

     #Do some crawling of javascript created content with Selenium 
     sel.get_text("//div") 
     yield item 
+0

Ни ссылки полезно больше, поэтому StackOverflow спрашивает, что вы по крайней мере суммировать страницы здесь. Можете ли вы сказать еще несколько или найти исходные ответы? Благодаря! – nealmcb

3

Насколько я знаю, лоскутная гусеничный реализовано более urrlib2 и URLLIB явно не работают с JS. Для работы с js вы можете использовать qt webkit или selenium, например. Или вы можете найти все ссылки ajax на странице и посмотреть, как реализован обмен данными с сервером и косвенно передать ответ на сервер api.

+0

@Dennis: Спасибо за Ваш ответ –

7

Если вы хотите, чтобы проверить достаточно большой, функциональный базовый код, который использует Scrapy и селен, проверьте https://github.com/nicodjimenez/bus_catchers. Вот более простой пример.

# stripped down BoltBus script 
from selenium import webdriver 
from selenium.common.exceptions import TimeoutException 
from selenium.webdriver.support.ui import WebDriverWait 
from selenium.webdriver.support import expected_conditions as EC 
from selenium.webdriver.common.keys import Keys 
from scrapy.selector import HtmlXPathSelector 
from scrapy.http import Response 
from scrapy.http import TextResponse 
import time 

# set dates, origin, destination 
cityOrigin="Baltimore" 
cityDeparture="New York" 
day_array=[0] 
browser = webdriver.Firefox() 

# we are going the day of the days of the month from 15,16,...,25 
# there is a discrepancy between the index of the calendar days and the day itself: for example day[10] may correspond to Feb 7th 
for day in day_array: 

    # Create a new instance of the Firefox driver 
    browser.get("http://www.boltbus.com") 

    # click on "region" tab 
    elem_0=browser.find_element_by_id("ctl00_cphM_forwardRouteUC_lstRegion_textBox") 
    elem_0.click() 
    time.sleep(5) 

    # select Northeast 
    elem_1=browser.find_element_by_partial_link_text("Northeast") 
    elem_1.click() 
    time.sleep(5) 

    # click on origin city 
    elem_2=browser.find_element_by_id("ctl00_cphM_forwardRouteUC_lstOrigin_textBox") 
    elem_2.click() 
    time.sleep(5) 

    # select origin city 
    elem_3=browser.find_element_by_partial_link_text(cityOrigin) 
    elem_3.click() 
    time.sleep(5) 

    # click on destination city 
    elem_4=browser.find_element_by_id("ctl00_cphM_forwardRouteUC_lstDestination_textBox") 
    elem_4.click() 
    time.sleep(5) 

    # select destination city 
    elem_5=browser.find_element_by_partial_link_text(cityDeparture) 
    elem_5.click() 
    time.sleep(5) 

    # click on travel date 
    travel_date_elem=browser.find_element_by_id("ctl00_cphM_forwardRouteUC_imageE") 
    travel_date_elem.click()  

    # gets day rows of table 
    date_rows=browser.find_elements_by_class_name("daysrow") 

    # select actual day (use variable day) 
    # NOTE: you must make sure these day elements are "clickable" 
    days=date_rows[0].find_elements_by_xpath("..//td") 
    days[day].click() 
    time.sleep(3) 

    # retrieve actual departure date from browser 
    depart_date_elem=browser.find_element_by_id("ctl00_cphM_forwardRouteUC_txtDepartureDate") 
    depart_date=str(depart_date_elem.get_attribute("value")) 

    # PARSE TABLE 

    # convert html to "nice format" 
    text_html=browser.page_source.encode('utf-8') 
    html_str=str(text_html) 

    # this is a hack that initiates a "TextResponse" object (taken from the Scrapy module) 
    resp_for_scrapy=TextResponse('none',200,{},html_str,[],None) 

    # takes a "TextResponse" object and feeds it to a scrapy function which will convert the raw HTML to a XPath document tree 
    hxs=HtmlXPathSelector(resp_for_scrapy) 

    # the | sign means "or" 
    table_rows=hxs.select('//tr[@class="fareviewrow"] | //tr[@class="fareviewaltrow"]') 
    row_ct=len(table_rows) 

    for x in xrange(row_ct): 

     cur_node_elements=table_rows[x] 
     travel_price=cur_node_elements.select('.//td[@class="faresColumn0"]/text()').re("\d{1,3}\.\d\d") 

     # I use a mixture of xpath selectors to get me to the right location in the document, and regular expressions to get the exact data 

     # actual digits of time 
     depart_time_num=cur_node_elements.select('.//td[@class="faresColumn1"]/text()').re("\d{1,2}\:\d\d") 

     # AM or PM (time signature) 
     depart_time_sig=cur_node_elements.select('.//td[@class="faresColumn1"]/text()').re("[AP][M]") 

     # actual digits of time 
     arrive_time_num=cur_node_elements.select('.//td[@class="faresColumn2"]/text()').re("\d{1,2}\:\d\d") 

     # AM or PM (time signature) 
     arrive_time_sig=cur_node_elements.select('.//td[@class="faresColumn2"]/text()').re("[AP][M]") 

     print "Depart date: " + depart_date 
     print "Depart time: " + depart_time_num[0] + " " + depart_time_sig[0] 
     print "Arrive time: " + arrive_time_num[0] + " " + arrive_time_sig[0] 
     print "Cost: " + "$" + travel_price[0] 
     print "\n" 
+0

Эй, @nicodjimenez, спасибо за ваш код. Я получил его, чтобы работать, за исключением того, что он выбирает даты. Я не понял, когда вы говорите: «Мы ходим в день дней месяца с 15,16, ..., 25». Кроме того, вы отмечаете: «вы должны убедиться, что эти элементы дня« доступны для клика ». Не могли бы вы немного рассказать об этом? – cd98

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