学科分类
目录
网络爬虫

制作Spider爬取网页

在Scrapy-Redis中,分别提供了两个爬虫类实现爬取网页的操作:RedisSpider、RedisCrawlSpider,它们都位于scrapy_redis.spiders模块中。其中,RedisSpider是Spider的派生类,RedisCrawlSpider是CrawlSpider类的派生类,它们默认已经拥有了父类中的成员。此外,它们还定义了自己的若干属性,主要包含如下属性:

1. redis_key

表示Redis数据库从哪里获取起始网址,它是一个队列的名称,相当于start_urls。项目启动时,不会立即执行爬取操作,而是停在原地等待命令。例如,现在有5台机器,每台机器都已经把项目启动起来,它们都等待着redis_key指令,将第一批请求给它们执行,这样就做到了任务统一调度。

redis_key的一般命名格式为:

类名(小写): start_urls

redis_key的示例如下:

redis_key = 'aqi:start_urls'

有时,我们需要将爬取到的URL存放在远程的Redis数据库中,所以一般有如下操作:

redis = Redis(host=REDIS_HOST, port=REDIS_PORT, db=REDIS_DB,
   password=REDIS_PASSWD)
# spider:start_urls是Redis中存放url的队列名称
redis.lpush('spider:start_urls', self.url + u)  

连接到数据库存放URL,这样可以保证不断有URL添加,爬虫能够一直继续下去。

2. allowed_domains

这个属性既可以按照Spider中原有的写法,直接给出爬虫搜索的域名范围,也可以动态获取域名。例如,redis_key的值为“hr.tencent.com”,allowed_domains属性能自动获取到这个域名,将其作为允许的域名范围,具体设置如下:

def __init__(self, *args, **kwargs):
  domain = kwargs.pop('domain', '')
  self.allowed_domains = filter(None, domain.split(','))
  super(**当前类名**, self).__init__(*args, **kwargs)

两种设置使用哪种都可以,可任选其一。

在mySpider项目中,创建一个用于编写爬虫的文件,命名为itcast,爬取域的范围为“itcast.cn”。在终端中切换目录至spiders,输入如下命令:

scrapy genspider itcast "itcast.cn"

运行上述命令,PyCharm的spiders目录下增加了itcast.py文件。在该文件中,默认生成的类代码中已经继承了scrapy.Spider类。为了能让其具有Scrapy-Redis的功能,需要把继承的父类修改为RedisSpider,另外还要删除该文件中自带的start_urls,增加redis_key属性的设置,具体代码如下。

# -*- coding: utf-8 -*-
import scrapy
from scrapy_redis.spiders import RedisSpider
class ItcastSpider(RedisSpider):
  name = 'itcast'
  allowed_domains = ['itcast.cn']
  redis_key = 'itcast:start_urls'
  def parse(self, response):
     pass

接下来就可以解析网页了。在parse方法中,将得到的数据封装成一个MyspiderItem对象,每个对象保存一个讲师的信息,然后将所有的对象保存在一个列表items里。代码如下所示。

def parse(self, response):
     items = [] #存放老师信息的集合
     for each in response.xpath("//div[@class='li_txt']"):
       # 将我们得到的数据封装到一个'MyspiderItem'对象
       item = MyspiderItem()
       # extract方法返回的都是Unicode字符串
       name = each.xpath("h3/text()").extract()
       title = each.xpath("h4/text()").extract()
       info = each.xpath("p/text()").extract()
       # XPath返回的是包含一个元素的列表
       item["name"] = name[0]
       item["title"] = title[0]
       item["info"] = info[0]
       items.append(item)
     # 返回数据,不经过pipeline
     return items

我们之前在项目的mySpider/items.py目录下定义了MyspiderItem类,需要将该类引入到itcast.py文件中,代码如下。

from mySpider.items import MyspiderItem
点击此处
隐藏目录