1

下面是我整理的一个 Scrapy 蜘蛛,用于从网页中提取一些元素。我从另一个 Stack Overflow 解决方案借用了这个解决方案。它有效,但我需要更多。验证后,我需要能够在 start_requests 方法内的 for 循环中指定的一系列页面。

是的,我确实找到了讨论这个问题的 Scrapy 文档以及之前非常相似的解决方案。两者似乎都没有多大意义。据我所知,我需要以某种方式创建一个请求对象并继续传递它,但似乎无法弄清楚如何做到这一点。

预先感谢您的帮助。

from scrapy.spider import BaseSpider
from scrapy.selector import HtmlXPathSelector
import re

class MyBasicSpider(BaseSpider):
    name = "awBasic"
    allowed_domains = ["americanwhitewater.org"]

    def start_requests(self):
        '''
        Override BaseSpider.start_requests to crawl all reaches in series
        '''
        # for every integer from one to 5000
        for i in xrange(1, 50): # 1 to 50 for testing

            # convert to string
            iStr = str(i)

            # add leading zeros to get to four digit length
            while len(iStr) < 4:
                iStr = '0{0}'.format(iStr)

            # call make requests
            yield self.make_requests_from_url('https://mycrawlsite.com/{0}/'.format(iStr))

    def parse(self, response):

        # create xpath selector object instance with response
        hxs = HtmlXPathSelector(response)

        # get part of url string
        url = response.url
        id = re.findall('/(\d{4})/', url)[0]

        # selector 01
        attribute01 = hxs.select('//div[@id="block_1"]/text()').re('([^,]*)')[0]

        # selector for river section
        attribute02 = hxs.select('//div[@id="block_1"]/div[1]/text()').extract()[0]

        # print results
        print('\tID: {0}\n\tAttr01: {1}\n\tAttr02: {2}').format(reachId, river, reachName) 
4

1 回答 1

3

您可能必须从不同的角度解决问题:

  • 首先,抓取主页;它包含一个登录表单,因此您可以使用FormRequest来模拟用户登录;您的parse方法可能看起来像这样:

    def parse(self, response):
        return [FormRequest.from_response(response,
                    formdata={'username': 'john', 'password': 'secret'},
                    callback=self.after_login)]
    
  • after_login您检查身份验证是否成功,通常通过扫描错误消息的响应;如果一切顺利并且您已登录,您可以开始为您所追求的页面生成请求:

    def after_login(self, response):
        if "Login failed" in response.body:
            self.log("Login failed", level=log.ERROR)
        else:
            for i in xrange(1, 50): # 1 to 50 for testing
                # convert to string
                iStr = str(i)
    
                # add leading zeros to get to four digit length
                while len(iStr) < 4:
                    iStr = '0{0}'.format(iStr)
    
                # call make requests
                yield Request(url='https://mycrawlsite.com/{0}/'.format(iStr),
                              callback=self.scrape_page)
    
  • scrape_page将与您创建请求的每个页面一起调用;在那里,您最终可以使用 XPath、正则表达式等提取所需的信息。

顺便说一句,您不应该手动填充数字 0;format如果您使用正确的格式说明符,它将为您完成。

于 2013-11-09T01:19:20.523 回答