本章将从案例开始介绍python scrapy框架,更多内容请参考:python学习指南

入门案例

学习目标

  • 创建一个Scrapy项目
  • 定义提取的结构化数据(Item)
  • 编写爬取网站的Spider并提取出结构化数据(Item)
  • 编写Item Pipelines来存储提取到的Item(即结构化数据)

一、新建项目(scrapy startproject)

  • 在开始爬取之前,必须创建一个新的Scrapy项目。进入自定义的项目目录中,运行下列命令:
scrapy startproject cnblogSpider
  • 其中,cnblogSpider为项目名称,可以看到将会创建一个cnblogSpider文件夹,目录结构大致如下:

scrapy.cfg:项目部署文件

cnblogSpider/: 该项目的python模块,之后可以在此加入代码

cnblogSpider/items.py: 项目中的item文件。

cnblogSpider/pipelines.py: 项目中的Pipelines文件。

cnblogSpider/settings.py: 项目的配置文件。

cnblogSpider/spiders/: 放置Spider代码的目录。

二、明确目标(mySpider/items.py)

我们打算抓取:"http://www.cnblogs.com/miqi1992/default.html?page=2" 网站里博客地址、标题、创建时间、文本。

  1. 打开cnblogSpider目录下的items.py

  2. item定义结构化数据字段,用来保存爬取到的数据,有点像Python中的dict,但是提供了一些额外的保护减少错误。

  3. 可以通过创建一个scrapy.item类,并且定义类型为scrapy.Field的类属性来定义一个Item(可以理解成类似于ORM的映射关系)。

  4. 接下来,创建一个CnblogspiderItem类,和模型item模型(model)。

import scrapy

class CnblogspiderItem(scrapy.Item):
# define the fields for your item here like:
url = scrapy.Field()
time = scrapy.Field()
title = scrapy.Field()
content = scrapy.Field()

三、制作爬虫(spiders/cnblogsSpider.py)

爬虫功能主要分两步:

1. 爬数据

  • 在当前目录下输入命令,将在cnblogSpider/spiders目录下创建一个名为cnblog的爬虫,并制定爬取域的范围:
scrapy genspider cnblog "cnblogs.com"
  • 打开cnblogSpider/spiders目录下的cnblog,默认增加了下列代码:
# -*- coding: utf-8 -*-
import scrapy class CnblogSpider(scrapy.Spider):
name = 'cnblog'
allowed_domains = ['cnblogs.com']
start_urls = ['http://cnblogs.com/'] def parse(self, response):
pass

其实也可以由我们自行创建cnblog.py并编写上面的代码,只不过使用命令可以免去编写固定代码的麻烦

要建立一个Spider,你必须用scrapy.Spider类创建一个子类,并确定了三个强制的属性和一个方法。

  • name = "": 这个爬虫的识别名称,必须是唯一的,在不同的爬虫必须定义不同的名字。
  • allow_domains=[]: 是搜索的域名范围,也就是爬虫的约束区域,规定爬虫只爬取这个域名下的网页,不存在的URL会被忽略。
  • start_urls=():爬取的URL元祖/列表。爬虫从这里开始爬取数据,所以,第一次下载的数据将会从这些urls开始。其他子URL将会从这些起始URL中继承性生成。
  • parse(self, response):解析的方法,每个初始URL完成下载后将被调用,调用的时候传入从每一个URL传回的Response对象来作为唯一参数,主要作用如下:
    1. 负责解析返回的网页数据(respose.body),提取结构化数据(生成item)
    2. 生成需要下一页的URL请求

将start_urls的值改为需要爬取的第一个url

start_urls=("http://www.cnblogs.com/miqi1992/default.html?page=2")

修改parse()方法

def parse(self, response):
filename = "cnblog.html"
with open(filename, 'w') as f:
f.write(response.body)

然后运行一下看看,在cnblogSpider目录下运行:

scrapy crawl cnblog

是的,就是cnblog,看上面代码,它是CnblogSpider类的name属性,也就是scrapy genspider命令的唯一爬虫名。

运行之后,如果打印的日志出现[scrapy]INFO: Spider closed(finished),代表执行完成。之后当前文件夹中就出现了一个cnblog.html文件,里面就是我们刚刚要爬取的网页的全部源代码信息。

#注意,Python2.x默认编码环境是ASCII,当和取回的数据编码格式不一致时,可能会造成乱码;
#我们可以指定保存内容的编码格式,一般情况下,我们可以在代码最上方添加:
import os
reload(sys)
sys.setdefaultencoding('utf-8')
#这三行代码是Python2.x里面解决中文编码的万能钥匙,警告这么多年的吐槽后Python3学乖了,默认编码是Unicode了

2.爬数据

  • 爬取整个网页完毕,接下来就是取过程了,首先观察页面源码:

<div class="day">
<div class="dayTitle">...</div>
<div class="postTitle">...</div>
<div class="postCon">...</div>
</div>
  • XPath表达式如下:

    • 所有文章:.//*[@class='day']
    • 文章发表时间:.//*[@class='dayTitle']/a/text()
    • 文章标题内容:.//*[@class='postTitle']/a/text()
    • 文章摘要内容:.//*[@class='postCon']/div/text()
    • 文章链接:.//*[@class='postTitle']/a/@href

是不是一目了然?直接上XPath开始提取数据吧。

  • 我们之前在cnblogSpider/items.py里定义了一个CnblogItem类。这里引入进来
from cnblogSpider.items import CnblogspiderItem
  • 然后将我们得到的数据封装到一个CnblogspiderItem对象中,可以保存每个博客的属性:

form cnblogSpider.items import CnblogspiderItem def parse(self, response):
# print(response.body)
# filename = "cnblog.html"
# with open(filename, 'w') as f:
# f.write(response.body) #存放博客的集合
items = [] for each in response.xpath(".//*[@class='day']"):
item = CnblogspiderItem()
url = each.xpath('.//*[@class="postTitle"]/a/@href').extract()[0]
title = each.xpath('.//*[@class="postTitle"]/a/text()').extract()[0]
time = each.xpath('.//*[@class="dayTitle"]/a/text()').extract()[0]
content = each.xpath('.//*[@class="postCon"]/div/text()').extract()[0] item['url'] = url
item['title'] = title
item['time'] = time
item['content'] = content items.append(item) #直接返回最后数据
return items
  • 我们暂时先不处理管道,后面会详细介绍。

保存数据

scrapy保存信息的最简单的方法主要有四种, -o 输出指定格式的文件,命令如下:

#json格式,默认为Unicode编码
scrapy crawl cnblog -o cnblog.json #json lines格式,默认为Unicode编码
scrapy crawl cnblog -o cnblog.jsonl #csv逗号表达式,可用excel打开
scrapy crawl cnblog -o cnblog.csv #xml格式
scrapy crawl cnblog -o cnblog.xml

思考

如果将代码改成下面形式,结果完全一样

请思考yield在这里的作用:

form cnblogSpider.items import CnblogspiderItem

def parse(self, response):
# print(response.body)
# filename = "cnblog.html"
# with open(filename, 'w') as f:
# f.write(response.body) #存放博客的集合
# items = [] for each in response.xpath(".//*[@class='day']"):
item = CnblogspiderItem()
url = each.xpath('.//*[@class="postTitle"]/a/@href').extract()[0]
title = each.xpath('.//*[@class="postTitle"]/a/text()').extract()[0]
time = each.xpath('.//*[@class="dayTitle"]/a/text()').extract()[0]
content = each.xpath('.//*[@class="postCon"]/div/text()').extract()[0] item['url'] = url
item['title'] = title
item['time'] = time
item['content'] = content # items.append(item)
#将获取到的数据交给pipelines
yield item #直接返回最后数据,不经过pipelines
#return items

参考:

  1. Python参考手册

Python爬虫Scrapy(二)_入门案例的更多相关文章

  1. python爬虫Scrapy(一)-我爬了boss数据

    一.概述 学习python有一段时间了,最近了解了下Python的入门爬虫框架Scrapy,参考了文章Python爬虫框架Scrapy入门.本篇文章属于初学经验记录,比较简单,适合刚学习爬虫的小伙伴. ...

  2. Python爬虫之xpath语法及案例使用

    Python爬虫之xpath语法及案例使用 ---- 钢铁侠的知识库 2022.08.15 我们在写Python爬虫时,经常需要对网页提取信息,如果用传统正则表达去写会增加很多工作量,此时需要一种对数 ...

  3. python爬虫scrapy框架——人工识别登录知乎倒立文字验证码和数字英文验证码(2)

    操作环境:python3 在上一文中python爬虫scrapy框架--人工识别知乎登录知乎倒立文字验证码和数字英文验证码(1)我们已经介绍了用Requests库来登录知乎,本文如果看不懂可以先看之前 ...

  4. python爬虫scrapy项目详解(关注、持续更新)

    python爬虫scrapy项目(一) 爬取目标:腾讯招聘网站(起始url:https://hr.tencent.com/position.php?keywords=&tid=0&st ...

  5. Python爬虫利器二之Beautiful Soup的用法

    上一节我们介绍了正则表达式,它的内容其实还是蛮多的,如果一个正则匹配稍有差池,那可能程序就处在永久的循环之中,而且有的小伙伴们也对写正则表达式的写法用得不熟练,没关系,我们还有一个更强大的工具,叫Be ...

  6. Python爬虫实战二之爬取百度贴吧帖子

    大家好,上次我们实验了爬取了糗事百科的段子,那么这次我们来尝试一下爬取百度贴吧的帖子.与上一篇不同的是,这次我们需要用到文件的相关操作. 前言 亲爱的们,教程比较旧了,百度贴吧页面可能改版,可能代码不 ...

  7. 转 Python爬虫实战二之爬取百度贴吧帖子

    静觅 » Python爬虫实战二之爬取百度贴吧帖子 大家好,上次我们实验了爬取了糗事百科的段子,那么这次我们来尝试一下爬取百度贴吧的帖子.与上一篇不同的是,这次我们需要用到文件的相关操作. 本篇目标 ...

  8. ArcGIS for Desktop入门教程_第四章_入门案例分析 - ArcGIS知乎-新一代ArcGIS问答社区

    原文:ArcGIS for Desktop入门教程_第四章_入门案例分析 - ArcGIS知乎-新一代ArcGIS问答社区 1 入门案例分析 在第一章里,我们已经对ArcGIS系列软件的体系结构有了一 ...

  9. [Python爬虫] scrapy爬虫系列 <一>.安装及入门介绍

    前面介绍了很多Selenium基于自动测试的Python爬虫程序,主要利用它的xpath语句,通过分析网页DOM树结构进行爬取内容,同时可以结合Phantomjs模拟浏览器进行鼠标或键盘操作.但是,更 ...

随机推荐

  1. linq中group by

    本文导读:LINQ定义了大约40个查询操作符,如select.from.in.where.group 以及order by,借助于LINQ技术,我们可以使用一种类似SQL的语法来查询任何形式的数据.L ...

  2. Python中__new__和__init__区别

    __new__:创建对象时调用,会返回当前对象的一个实例 __init__:创建完对象后调用,对当前对象的一些实例初始化,无返回值 1.在类中,如果__new__和__init__同时存在,会优先调用 ...

  3. 打印中文dict list的各种姿势

    在开发过程中,我们经常需要打印一些变量的值,便于调试.这个时候就会发现如果在dict list这些容器中,如果包含中文字符,不管是str类型,还是unicode类型,都打印不出来.如下: >&g ...

  4. java参数传值方式

     java参数有值类型和引用类型两种.所以java参数的传值也就从这两个方面分析. 从内存模型来说参数传递更为直观一些,这里涉及到两种类型的内存:栈内存(stack)和堆内存(heap).   基本类 ...

  5. eclipse搭建maven ssm项目

    file --> new --> maven project -->创建个简单的maven项目 会报错,没事 右键 properties 先去掉,然后再勾上 接下来配置maven的相 ...

  6. idea for Mac 日常配置&快捷键

    配置: 1.jdk:file > project structure -- Project SDK; 快捷键: geter adn seter :command+n command+点到具体方法 ...

  7. Vue.js简单的应用

    1:一个简单实现 下面代码部分: <body> <div id="myDiv1"> {{userName}} </div> </body& ...

  8. BST 解析 (一)

    这篇博文主要初步介绍Binary Search Tree(BST)的一些基本功能以及应用场景,由于BST的相关知识比较多,下一节会接着补充BST的一些功能.这一节主要分为以下三个要素: BST 的定义 ...

  9. Mysql第一周

    前言:好久不见,我又来写博客拉.上个月只写了几篇django-rest-framework的,而且还是根据官网的英文写的.干货不多,内心还是有点羞耻的…… 简单说下我11月去干嘛了.11月初美图给我发 ...

  10. sql查询语句报错处理——ERROR: failed to find conversion function from unknown to text

    今天遇到写存储过程遇到的一个小问题,在查询语句中使用到了自定义的数当做列的值,然后想给这一列起一个别名 ,就直接在后面用了 as 别名.执行存储过程,存储过程报错,ERROR: failed to f ...