scrapy pagination selenium python

时间:2013-07-30 02:55:53

标签: python selenium web-scraping scrapy

我正在尝试使用分页从表中删除链接。我可以让Selenium遍历页面,我可以从第一页获取链接,但是如果我尝试将两者结合起来,当我到达最后一页并且不再有下一页按钮,进程停止,我什么都没得到。

我不确定如何优雅地告诉事情只是将数据返回到csv。我正在使用while true:循环,所以这对我来说很令人费解。

另一个问题与我尝试使用xpath解析的链接有关。链接保存在两个不同的tr - 类中。一组在//tr[@class ="resultsY"]下,另一组在//tr[@class ="resultsW"]下,是否有一个OR语句我可以用来一次性定位所有链接?

我找到了一个解决方案: '//tr[@class ="resultsY"] | //tr[@class ="resultsW"]'每次都会给我一个错误。

这是html表:

<tr class="resultsW">
-<td></td>
-<td>
----<a href="fdafda"></a>        <----a link i'm after
-<td>
-<td></td>
</tr>
<tr class="resultsW">
-<td></td>
-<td>
----<a href="fdafda"></a>        <----a link i'm after
-<td>
-<td></td>
</tr>

这是我的scrapy:

import time
from scrapy.item import Item, Field
from selenium import webdriver
from scrapy.spider import BaseSpider
from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from scrapy.selector import HtmlXPathSelector

class ElyseAvenueItem(Item):
    link = Field()   
    link2 = Field()

class ElyseAvenueSpider(BaseSpider):
    name = "s1"
    allowed_domains = ["nces.ed.gov"]
    start_urls = [
    'https://nces.ed.gov/collegenavigator/']

    def __init__(self):
        self.driver = webdriver.Firefox()

    def parse(self, response):
        self.driver.get(response.url)
        select = Select(self.driver.find_element_by_id("ctl00_cphCollegeNavBody_ucSearchMain_ucMapMain_lstState"))
        select.deselect_by_visible_text("No Preference")
        select.select_by_visible_text("Alabama")
        self.driver.find_element_by_id("ctl00_cphCollegeNavBody_ucSearchMain_btnSearch").click()

#here is the while loop. it gets to the end of the table and says...no more "next page" and gives me the middle finger

        '''while True:
            el1 = self.driver.find_element_by_partial_link_text("Next Page")
            if el1:
                el1.click()
            else:
                #return(items)
                self.driver.close()'''
        hxs = HtmlXPathSelector(response)

        '''
#here i tried: titles = self.driver.find_elements_by_xpath('//tr[@class ="resultsW"] | //tr[@class ="resultsY"]') and i got an error saying that

        titles = self.driver.find_elements_by_xpath('//tr[@class ="resultsW"]')
        items = []
        for titles in titles:
            item = ElyseAvenueItem()

#here i'd like to be able to target all of the hrefs...not sure how

            link = titles.find_element_by_xpath('//tr[@class ="resultsW"]/td[2]/a')
            item ["link"] = link.get_attribute('href')
            items.append(item)
        yield(items)

1 个答案:

答案 0 :(得分:1)

将这篇文章分成三篇文章会增加你获得好答案的机会。

对于第一个问题,更准确地了解“过程停止而我什么也得不到”的意思是有帮助的。我没有看到您尝试将“链接”写入文件。我不明白为什么你在else条款中做了什么。

对于第二个问题,使用正则表达式可能会有所帮助。请参阅this

对于第三个问题,因为元素title是列表

titles = self.driver.find_elements_by_xpath('//tr[@class ="resultsW"]')

你可以做到

hrefs=[]
for titles in titles:
    href = titles.find_element_by_xpath('a').get_attribute('href')
    hrefs.append(href)

顺便说一句,如果您尝试做的只是从网页上删除链接,请考虑mechanizelxml.html和|或BeautifulSoup