我正在学习Python,并尝试在下拉菜单上将该页面抓取为特定值。之后,我需要单击结果表上的每个项目以检索特定信息。我可以选择该项目并在网络驱动程序上检索信息。但是我不知道如何将响应URL传递给crawlspider。
driver = webdriver.Firefox() driver.get('http://www.cppcc.gov.cn/CMS/icms/project1/cppcc/wylibary/wjWeiYuanList.jsp') more_btn = WebDriverWait(driver, 20).until( EC.visibility_of_element_located((By.ID, '_button_select')) ) more_btn.click() ## select specific value from the dropdown driver.find_element_by_css_selector("select#tabJcwyxt_jiebie > option[value='teyaoxgrs']").click() driver.find_element_by_css_selector("select#tabJcwyxt_jieci > option[value='d11jie']").click() search2 = driver.find_element_by_class_name('input_a2') search2.click() time.sleep(5) ## convert html to "nice format" text_html=driver.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) ## convert html to "nice format" text_html=driver.page_source.encode('utf-8') html_str=str(text_html) resp_for_scrapy=TextResponse('none',200,{},html_str,[],None)
这就是我被困住的地方。我能够使用上面的代码进行查询。但是,如何将 resp_for_scrapy 传递给 crawlspider ?我把 resp_for_scrapy 代替了 item, 但是那 没用 。
## spider class ProfileSpider(CrawlSpider): name = 'pccprofile2' allowed_domains = ['cppcc.gov.cn'] start_urls = ['http://www.cppcc.gov.cn/CMS/icms/project1/cppcc/wylibary/wjWeiYuanList.jsp'] def parse(self, resp_for_scrapy): hxs = HtmlXPathSelector(resp_for_scrapy) for post in resp_for_scrapy.xpath('//div[@class="table"]//ul//li'): items = [] item = Ppcprofile2Item() item ["name"] = hxs.select("//h1/text()").extract() item ["title"] = hxs.select("//div[@id='contentbody']//tr//td//text()").extract() items.append(item) ##click next page while True: next = self.driver.findElement(By.linkText("下一页")) try: next.click() except: break return(items)
任何建议将不胜感激!!!!
编辑 我在蜘蛛类之前包括了一个中间件类,可从下拉菜单中进行选择。但是现在没有错误,也没有结果。
class JSMiddleware(object): def process_request(self, request, spider): driver = webdriver.PhantomJS() driver.get('http://www.cppcc.gov.cn/CMS/icms/project1/cppcc/wylibary/wjWeiYuanList.jsp') # select from the dropdown more_btn = WebDriverWait(driver, 20).until( EC.visibility_of_element_located((By.ID, '_button_select')) ) more_btn.click() driver.find_element_by_css_selector("select#tabJcwyxt_jiebie > option[value='teyaoxgrs']").click() driver.find_element_by_css_selector("select#tabJcwyxt_jieci > option[value='d11jie']").click() search2 = driver.find_element_by_class_name('input_a2') search2.click() time.sleep(5) #get the response body = driver.page_source return HtmlResponse(driver.current_url, body=body, encoding='utf-8', request=request) class ProfileSpider(CrawlSpider): name = 'pccprofile2' rules = [Rule(SgmlLinkExtractor(allow=(),restrict_xpaths=("//div[@class='table']")), callback='parse_item')] def parse_item(self, response): hxs = HtmlXPathSelector(response) items = [] item = Ppcprofile2Item() item ["name"] = hxs.select("//h1/text()").extract() item ["title"] = hxs.select("//div[@id='contentbody']//tr//td//text()").extract() items.append(item) #click next page while True: next = response.findElement(By.linkText("下一页")) try: next.click() except: break return(items)
在使用Scrapy定期处理硒所需的页面 之前, 请使用Downloader Middleware捕获硒所需的页面: __
下载器中间件是一个挂钩Scrapy的请求/响应处理的框架。这是一个轻量级的低级系统,用于全局更改Scrapy的请求和响应。
这是一个使用PhantomJS的非常基本的示例:
from scrapy.http import HtmlResponse from selenium import webdriver class JSMiddleware(object): def process_request(self, request, spider): driver = webdriver.PhantomJS() driver.get(request.url) body = driver.page_source return HtmlResponse(driver.current_url, body=body, encoding='utf-8', request=request)
一旦您返回该代码HtmlResponse(或者TextResponse您真正想要的是),Scrapy将停止处理下载程序,并使用Spider的parse方法:
HtmlResponse
TextResponse
parse
如果它返回一个Response对象,Scrapy将不会费心调用任何其他process_request()或process_exception()方法,或适当的下载函数。它将返回该响应。总是在每个响应上调用已安装中间件的process_response()方法。
在这种情况下,parse除了页面上的JS已被执行之外,您可以继续像平常使用HTML一样继续使用Spider的方法。
提示:由于Downloader Middleware的process_request方法接受Spider作为参数,因此您可以在Spider中添加一个条件来检查是否需要处理JS,这将使您能够以完全相同的方式处理JS和非JS页面蜘蛛类。
process_request