scrapy爬虫:CrawlSpider用法与总结

Class scrapy.spiders.CrawlSpider
           爬取一般网站常用的 spider。其定义了一些规则(rule)来提供跟进 link 的方便的机制。 也许该 spider 并不是完全适合您的特定网站或项目,但其对很多情况都使用。因此您可以以其为起点,根据需求修改部分方法。当然您也可以实现自己的 spider。 除了从 Spider 继承过来的属性外,其提供了一个新的属性:
 rules:
         一个包含一个(或多个) Rule 对象的集合(list)。 每个 Rule 对爬取网站的动作定义了特定表现。 Rule 对象在下边会介绍。 如果多个 rule 匹配了相同的链接,则根据他们在本属性中被定义的顺序,第一个会被使用。

爬取规则(Crawling rules)

class scrapy.spiders.Rule(link_extractor, callback=None, cb_kwargs=None, follow=None, process_links=None, process_request=None)

link_extractor 是一个scrapy.linkxtractor.LinkExtractor 对象。其定义了如何从爬取到的页面提取链接。

callback 是一个 callable 或 string(该 spider 中同名的函数将会被调用)。从 link_extractor 中每获取到链接时将会调用该函数。该回调函数接受一个 response 作为其第一个参数,并返回一个包含 Item 以及(或) Request 对象(或者这两者的子类)的列表(list)。(注:编写爬虫规则时,避免把parse当作回调函数


关于实战中使用CrawlSpider的总结:

    1. 对于动态生成的链接,比如抓取网页中“下一页”的链接时,通常链接是动态生成的,此时xpath规则并不能提取到改链接。如下图所示:


图-1 下一页图标   

           
图-2 对应的网页源代码
此时,解决方案是:查看“下一页”链接的规律,一般是"****/index_1.html", "****/index_2.html"........该类形式。找到规律后手动生成下一页的url,并使用 Class scrapy.spiders.Request对象向生成的url发起请求。
 
      
  1. def find_urls(self, response):
  2. if response.body.find(u"下一页") != -1:
  3. url_new = ""
  4. page_num = int(re.search(r'createPageHTML.(\d+), 0, "index", "html".', response.body).group(1))
  5.            # 拆分链接,得到自己想要的链接
  6.   match = re.search(r'(http://www.nxdjw.gov.cn/[0-9a-zA-Z]{4}/)[a-zA-Z0-9/]*', response.url)
  7. if match:
  8. for i in range(page_num - 1): #生成"index_1.html" -- "index_(page_num-1).html"下一页连接
  9. url_new = match.group(1) + "index_" + str(i + 1) + ".html"
  10. yield Request(url_new)
                
     2. 抓取到的时间格式转换                    
 
       
  1. import time
  2. a = '20160101'
  3. dateArray = time.strptime(a, "%Y%m%d")
  4. otherStyleDate = time.strftime("%Y-%m-%d", dateArray)
      3. 正则表达式匹配中文字符(utf-8)
            [^\x00-\xff]   匹配一个中文字符        

      4.    descendant-or-self
                  descendant-or-self::p 可以匹配某个标签下所有的子标签p
 
        
  1. content_list = response.xpath('//div[@class="nr font14_lan"]/descendant-or-self::p/text()').extract()
5.  xpath表达式中//text()与/text()区别
//text()表示: 提取当前标签下所有含有文本的子标签的文本信息,而/text()只提取当前标签下的文本信息,若 无文本信息,则返回空(None)

6. 解决scrapy 打印日志信息到控制台中文乱码报错问题
打印到控制台的字符串必须用: str.encode('GB18030') 
 

你可能感兴趣的:(Scrapy爬虫)