Python的Scrapy爬虫框架简单学习笔记


Posted in Python onJanuary 20, 2016

 一、简单配置,获取单个网页上的内容。
(1)创建scrapy项目

scrapy startproject getblog

(2)编辑 items.py

# -*- coding: utf-8 -*-
 
# Define here the models for your scraped items
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.html
 
from scrapy.item import Item, Field
 
class BlogItem(Item):
  title = Field()
  desc = Field()

    (3)在 spiders 文件夹下,创建 blog_spider.py

需要熟悉下xpath选择,感觉跟JQuery选择器差不多,但是不如JQuery选择器用着舒服( w3school教程: http://www.w3school.com.cn/xpath/  )。

# coding=utf-8
 
from scrapy.spider import Spider
from getblog.items import BlogItem
from scrapy.selector import Selector
 
 
class BlogSpider(Spider):
  # 标识名称
  name = 'blog'
  # 起始地址
  start_urls = ['http://www.cnblogs.com/']
 
  def parse(self, response):
    sel = Selector(response) # Xptah 选择器
    # 选择所有含有class属性,值为‘post_item'的div 标签内容
    # 下面的 第2个div 的 所有内容
    sites = sel.xpath('//div[@class="post_item"]/div[2]')
    items = []
    for site in sites:
      item = BlogItem()
      # 选取h3标签下,a标签下,的文字内容 ‘text()'
      item['title'] = site.xpath('h3/a/text()').extract()
      # 同上,p标签下的 文字内容 ‘text()'
      item['desc'] = site.xpath('p[@class="post_item_summary"]/text()').extract()
      items.append(item)
    return items

(4)运行,

scrapy crawl blog # 即可

(5)输出文件。

        在 settings.py 中进行输出配置。

# 输出文件位置
FEED_URI = 'blog.xml'
# 输出文件格式 可以为 json,xml,csv
FEED_FORMAT = 'xml'

    输出位置为项目根文件夹下。

二、基本的 -- scrapy.spider.Spider

    (1)使用交互shell

dizzy@dizzy-pc:~$ scrapy shell "http://www.baidu.com/"
2014-08-21 04:09:11+0800 [scrapy] INFO: Scrapy 0.24.4 started (bot: scrapybot)
2014-08-21 04:09:11+0800 [scrapy] INFO: Optional features available: ssl, http11, django
2014-08-21 04:09:11+0800 [scrapy] INFO: Overridden settings: {'LOGSTATS_INTERVAL': 0}
2014-08-21 04:09:11+0800 [scrapy] INFO: Enabled extensions: TelnetConsole, CloseSpider, WebService, CoreStats, SpiderState
2014-08-21 04:09:11+0800 [scrapy] INFO: Enabled downloader middlewares: HttpAuthMiddleware, DownloadTimeoutMiddleware, UserAgentMiddleware, RetryMiddleware, DefaultHeadersMiddleware, MetaRefreshMiddleware, HttpCompressionMiddleware, RedirectMiddleware, CookiesMiddleware, ChunkedTransferMiddleware, DownloaderStats
2014-08-21 04:09:11+0800 [scrapy] INFO: Enabled spider middlewares: HttpErrorMiddleware, OffsiteMiddleware, RefererMiddleware, UrlLengthMiddleware, DepthMiddleware
2014-08-21 04:09:11+0800 [scrapy] INFO: Enabled item pipelines: 
2014-08-21 04:09:11+0800 [scrapy] DEBUG: Telnet console listening on 127.0.0.1:6024
2014-08-21 04:09:11+0800 [scrapy] DEBUG: Web service listening on 127.0.0.1:6081
2014-08-21 04:09:11+0800 [default] INFO: Spider opened
2014-08-21 04:09:12+0800 [default] DEBUG: Crawled (200) <GET http://www.baidu.com/> (referer: None)
[s] Available Scrapy objects:
[s]  crawler  <scrapy.crawler.Crawler object at 0xa483cec>
[s]  item    {}
[s]  request  <GET http://www.baidu.com/>
[s]  response  <200 http://www.baidu.com/>
[s]  settings  <scrapy.settings.Settings object at 0xa0de78c>
[s]  spider   <Spider 'default' at 0xa78086c>
[s] Useful shortcuts:
[s]  shelp()      Shell help (print this help)
[s]  fetch(req_or_url) Fetch request (or URL) and update local objects
[s]  view(response)  View response in a browser
 
>>> 
  # response.body 返回的所有内容
  # response.xpath('//ul/li') 可以测试所有的xpath内容
    More important, if you type response.selector you will access a selector object you can use to
query the response, and convenient shortcuts like response.xpath() and response.css() mapping to
response.selector.xpath() and response.selector.css()

        也就是可以很方便的,以交互的形式来查看xpath选择是否正确。之前是用FireFox的F12来选择的,但是并不能保证每次都能正确的选择出内容。

        也可使用:

scrapy shell 'http://scrapy.org' --nolog
# 参数 --nolog 没有日志

    (2)示例

from scrapy import Spider
from scrapy_test.items import DmozItem
 
 
class DmozSpider(Spider):
  name = 'dmoz'
  allowed_domains = ['dmoz.org']
  start_urls = ['http://www.dmoz.org/Computers/Programming/Languages/Python/Books/',
         'http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/,'
         '']
 
  def parse(self, response):
    for sel in response.xpath('//ul/li'):
      item = DmozItem()
      item['title'] = sel.xpath('a/text()').extract()
      item['link'] = sel.xpath('a/@href').extract()
      item['desc'] = sel.xpath('text()').extract()
      yield item

    (3)保存文件

        可以使用,保存文件。格式可以 json,xml,csv

scrapy crawl -o 'a.json' -t 'json'

    (4)使用模板创建spider

scrapy genspider baidu baidu.com
 
# -*- coding: utf-8 -*-
import scrapy
 
 
class BaiduSpider(scrapy.Spider):
  name = "baidu"
  allowed_domains = ["baidu.com"]
  start_urls = (
    'http://www.baidu.com/',
  )
 
  def parse(self, response):
    pass

    这段先这样吧,记得之前5个的,现在只能想起4个来了. :-(

    千万记得随手点下保存按钮。否则很是影响心情的(⊙o⊙)!

三、高级 -- scrapy.contrib.spiders.CrawlSpider

例子

#coding=utf-8
from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.contrib.linkextractors import LinkExtractor
import scrapy
 
 
class TestSpider(CrawlSpider):
  name = 'test'
  allowed_domains = ['example.com']
  start_urls = ['http://www.example.com/']
  rules = (
    # 元组
    Rule(LinkExtractor(allow=('category\.php', ), deny=('subsection\.php', ))),
    Rule(LinkExtractor(allow=('item\.php', )), callback='pars_item'),
  )
 
  def parse_item(self, response):
    self.log('item page : %s' % response.url)
    item = scrapy.Item()
    item['id'] = response.xpath('//td[@id="item_id"]/text()').re('ID:(\d+)')
    item['name'] = response.xpath('//td[@id="item_name"]/text()').extract()
    item['description'] = response.xpath('//td[@id="item_description"]/text()').extract()
    return item

其他的还有 XMLFeedSpider

  • class scrapy.contrib.spiders.XMLFeedSpider
  • class scrapy.contrib.spiders.CSVFeedSpider
  • class scrapy.contrib.spiders.SitemapSpider

四、选择器

>>> from scrapy.selector import Selector
  >>> from scrapy.http import HtmlResponse

    可以灵活的使用 .css() 和 .xpath() 来快速的选取目标数据

关于选择器,需要好好研究一下。xpath() 和 css() ,还要继续熟悉 正则.

    当通过class来进行选择的时候,尽量使用 css() 来选择,然后再用 xpath() 来选择元素的熟悉

五、Item Pipeline

Typical use for item pipelines are:
    • cleansing HTML data # 清除HTML数据
    • validating scraped data (checking that the items contain certain fields) # 验证数据
    • checking for duplicates (and dropping them) # 检查重复
    • storing the scraped item in a database # 存入数据库
    (1)验证数据

from scrapy.exceptions import DropItem
 
class PricePipeline(object):
  vat_factor = 1.5
  def process_item(self, item, spider):
    if item['price']:
      if item['price_excludes_vat']:
        item['price'] *= self.vat_factor
    else:
      raise DropItem('Missing price in %s' % item)

    (2)写Json文件

import json
 
class JsonWriterPipeline(object):
  def __init__(self):
    self.file = open('json.jl', 'wb')
  def process_item(self, item, spider):
    line = json.dumps(dict(item)) + '\n'
    self.file.write(line)
    return item

    (3)检查重复

from scrapy.exceptions import DropItem
 
class Duplicates(object):
  def __init__(self):
    self.ids_seen = set()
  def process_item(self, item, spider):
    if item['id'] in self.ids_seen:
      raise DropItem('Duplicate item found : %s' % item)
    else:
      self.ids_seen.add(item['id'])
      return item

    至于将数据写入数据库,应该也很简单。在 process_item 函数中,将 item 存入进去即可了。

Python 相关文章推荐
Python 错误和异常小结
Oct 09 Python
python中使用enumerate函数遍历元素实例
Jun 16 Python
浅谈python类属性的访问、设置和删除方法
Jul 25 Python
Python实现的科学计算器功能示例
Aug 04 Python
python数据类型判断type与isinstance的区别实例解析
Oct 31 Python
[原创]教女朋友学Python3(二)简单的输入输出及内置函数查看
Nov 30 Python
python 读取目录下csv文件并绘制曲线v111的方法
Jul 06 Python
python判断数字是否是超级素数幂
Sep 27 Python
pygame实现俄罗斯方块游戏(基础篇1)
Oct 29 Python
使用python编写一个语音朗读闹钟功能的示例代码
Jul 14 Python
Python如何在单元测试中给对象打补丁
Aug 03 Python
在 Python 中使用 7zip 备份文件的操作
Dec 11 Python
使用Python编写爬虫的基本模块及框架使用指南
Jan 20 #Python
Python中urllib+urllib2+cookielib模块编写爬虫实战
Jan 20 #Python
深入剖析Python的爬虫框架Scrapy的结构与运作流程
Jan 20 #Python
实践Python的爬虫框架Scrapy来抓取豆瓣电影TOP250
Jan 20 #Python
Python的爬虫包Beautiful Soup中用正则表达式来搜索
Jan 20 #Python
Python使用Beautiful Soup包编写爬虫时的一些关键点
Jan 20 #Python
Python制作爬虫抓取美女图
Jan 20 #Python
You might like
PHP实现递归无限级分类
2015/10/22 PHP
php版微信返回用户text输入的方法
2016/11/14 PHP
PHP实现搜索时记住状态的方法示例
2018/05/11 PHP
CI(CodeIgniter)框架中URL特殊字符处理与SQL注入隐患分析
2019/02/28 PHP
jquery使用jquery.zclip插件复制对象的实例教程
2013/12/04 Javascript
html文档中的location对象属性理解及常见的用法
2014/08/13 Javascript
JS动态添加iframe的代码
2015/09/14 Javascript
深入理解bootstrap框架之入门准备
2016/10/09 Javascript
js表单登陆验证示例
2016/10/19 Javascript
ECMAScript6 新特性范例大全
2017/03/24 Javascript
Vue中计算属性computed的示例解读
2017/07/26 Javascript
Angular中响应式表单的三种更新值方法详析
2017/08/22 Javascript
浅谈React组件之性能优化
2018/03/02 Javascript
使用vue-cli脚手架工具搭建vue-webpack项目
2019/01/14 Javascript
重学JS之显示强制类型转换详解
2019/06/30 Javascript
Python语言的12个基础知识点小结
2014/07/10 Python
Python教程之全局变量用法
2016/06/27 Python
Python实现将不规范的英文名字首字母大写
2016/11/15 Python
NumPy 如何生成多维数组的方法
2018/02/05 Python
python对离散变量的one-hot编码方法
2018/07/11 Python
Python人脸识别第三方库face_recognition接口说明文档
2019/05/03 Python
python如何解析配置文件并应用到项目中
2019/06/27 Python
keras 特征图可视化实例(中间层)
2020/01/24 Python
Django实现微信小程序支付的示例代码
2020/09/03 Python
Algenist奥杰尼官网:微藻抗衰老护肤品牌
2017/07/15 全球购物
LN-CC英国:伦敦时尚生活的缩影
2019/09/01 全球购物
linux面试题参考答案(11)
2016/11/26 面试题
党的群众路线教育实践活动督导组工作情况汇报
2014/10/28 职场文书
党的群众路线学习笔记
2014/11/06 职场文书
校本课程教学计划
2015/01/19 职场文书
安全教育第一课观后感
2015/06/17 职场文书
本地通过nginx配置反向代理的全过程记录
2021/03/31 Servers
详解Laravel框架的依赖注入功能
2021/05/27 PHP
《废话连篇——致新手》——chinapizza
2022/04/05 无线电
Python+OpenCV实现图片中的圆形检测
2022/04/07 Python
mysql全面解析json/数组
2022/07/07 MySQL