Python3 爬虫之 Scrapy 核心功能实现(二)
基于 Python 3.6.2 的 Scrapy 爬虫框架使用,Scrapy 的搭建过程请参照本人的另一篇博客:Python3 爬虫之 Scrapy 框架安装配置(一)
1. 爬虫项目创建
在抓取之前,需要新建一个 Scrapy 工程。进入一个你想用来保存代码的目录,比如 G:\projects 然后执行:
scrapy startproject SinanewsSpider
这个命令会在当前目录下创建一个新目录 SinanewsSpider,这就是此爬虫的项目名称,后面会使用到。

成功创建爬虫项目文件结构后,使用:tree /f 查看文件层级的结构关系

这些文件主要是:
scrapy.cfg: 项目配置文件
SinanewsSpider/: 项目python模块, 代码将从这里导入
SinanewsSpider/items.py: 项目items文件
SinanewsSpider/pipelines.py: 项目管道文件
SinanewsSpider/settings.py: 项目配置文件
SinanewsSpider/spiders: 放置spider的目录
2. 定义item
编辑 items.py 文件,items 是将要装载抓取的数据的容器,它工作方式像 python 里面的字典,但它提供更多的保护,比如对未定义的字段填充以防止拼写错误。在 items.py 文件里,scrapy 需要我们定义一个容器用于放置爬虫抓取的数据,它通过创建一个scrapy.Item 类来声明,定义它的属性为scrpy.Field 对象,就像是一个对象关系映射(ORM, Object Relational Mapping)。我们通过将需要的 item 模型化,来控制从站点获得的新闻数据,比如我们要获得新闻的标题项、内容项、发表时间、图片链接地址和页面链接地址,则定义这5种属性的域。Scrapy 框架已经定义好了基础的 item,我们自己的 item 只需继承 scrapy.Item 即可。
# -*- coding: utf-8 -*- # Define here the models for your scraped items
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.html import scrapy class SinanewsspiderItem(scrapy.Item): #定义数据项类,从scrapy.Item继承
# define the fields for your item here like:# name = scrapy.Field()
title = scrapy.Field() #定义标题项
content = scrapy.Field() #定义内容项
pubtime = scrapy.Field() #定义发表时间
imageUrl = scrapy.Field() #定义图片链接地址
Url = scrapy.Field() #定义页面链接地址
3. 编写爬虫 Spider
新建 SinanewsSpider.py 文件, Scrapy 框架已经帮助我们定义好了基础爬虫,只需要从 scrapy.spider 继承,并重写相应的解析函数 parse 即可。其中会涉及到使用 xPath 获取页面元素路径的操作,xPaht 是 XML 页面路径语言,使用路径表达式来选取 XML 文档中的节点或节点集,节点是通过沿着路径(Path)或者步(Steps)来选取的,html 是 XML 的子集,当然同样适用,有兴趣的读者可以自行查阅相关的 Xpath 文档。
# -*- coding: utf-8 -*-
from scrapy.spiders import Spider
from scrapy.selector import Selector
from scrapy import signals
from scrapy.crawler import CrawlerRunner
from scrapy.utils.project import get_project_settings
from scrapy.utils.log import configure_logging
from scrapy.xlib.pydispatch import dispatcher
from twisted.internet import reactor
from time import ctime,sleep
from scrapy.spiders import Spider
from scrapy.selector import Selector
from scrapy import signals
from scrapy.crawler import CrawlerRunner
from scrapy.utils.project import get_project_settings
from scrapy.xlib.pydispatch import dispatcher
from twisted.internet import reactor
from SinanewsSpider.items import SinanewsspiderItem
from scrapy.http import Request
import logging
import MySQLdb
import scrapy
from scrapy.utils.response import get_base_url
from scrapy.utils.url import urljoin_rfc
#以上是一些依赖包的导入
class SinanewsSpider(scrapy.Spider):
name = "SinanewsSpider"
start_urls = []
def __init__(self):
self.start_urls = ["http://roll.news.sina.com.cn/news/gnxw/gdxw1/index.shtml"] def parse(self, response):
for url in response.xpath('//ul/li/a/@href').extract():
yield scrapy.Request(url, callback=self.parse_detail) nextLink = []
nextLink = response.xpath('//div[@class="pagebox"]/span[last()-1]/a/@href').extract()
if nextLink:
nextLink = nextLink[0]
nextpage= nextLink.split('./')[1]
yield Request("http://roll.news.sina.com.cn/news/gnxw/gdxw1/" + nextpage,callback=self.parse) def parse_detail(self, response):
item = SinanewsspiderItem()
item['title'] = response.xpath('//h1[@class="main-title"]/text()').extract()[0]
content = ''
for con in response.xpath('//div[@id="article"]/p/text()').extract():
content = content + con
item['content'] = content
item['pubtime'] = response.xpath('//span[@class="date"]/text()').extract()[0]
imageurl = ''
for img in response.xpath('//div[@id="article"]/div[@class="img_wrapper"]/img/@src').extract():
imageurl = imageurl + img+'|'
item['imageUrl'] = imageurl
item['Url'] = response.url
yield item
4. 数据存储
编辑 pipelines.py 文件,用于将 items 中的数据存储到数据库中。
首先,创建 sinanews 数据库,并创建 SinaLocalNews 数据表,用于存储爬到的新闻数据:
mysql> create database sinanews;
mysql> use sinanews;
mysql> CREATE TABLE SinaLocalNews (
-> id int(11) NOT NULL AUTO_INCREMENT,
-> title VARCHAR(100),
-> content TEXT,
-> imageUrl VARCHAR(2000),
-> Url VARCHAR(1000),
-> pubtime DATETIME,
-> PRIMARY KEY (id)
-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.96 sec)
创建数据库:sinanews

创建数据表:SinaLocalNews

然后,在 process_item 方法中定义数据库操作的代码,process_item 方法在 pipeline 类中会默认执行:
# -*- coding: utf-8 -*- # Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html
import MySQLdb class SinanewsspiderPipeline(object):
con = MySQLdb.connect(host='localhost', port=3306, user='root', passwd='', db='sinanews', charset='utf8')
cur = con.cursor()
def process_item(self, item, spider):
sql = "INSERT INTO SinaLocalNews(title, content, imageUrl, Url, pubtime) VALUES ('%s', '%s', '%s', '%s', trim(replace(replace(replace(left('%s',16),'年','-'),'月','-'),'日',' ')))" % (item['title'], item['content'], item['imageUrl'], item['Url'], item['pubtime'])
self.cur.execute(sql)
self.con.commit()
其中,host 为数据库服务器的地址,port 为数据库服务器监听的端口号,usr 指定数据库的用户名,passwd 则为数据库密码,db 为所要连接的具体数据库实例的名称,charset 指定你目标数据库的编码字符集。
5. 激活 pipeline 管道
编辑 settings.py 文件,添加如下代码:
BOT_NAME = 'SinanewsSpider' SPIDER_MODULES = ['SinanewsSpider.spiders']
NEWSPIDER_MODULE = 'SinanewsSpider.spiders' ROBOTSTXT_OBEY = True ITEM_PIPELINES = {
'SinanewsSpider.pipelines.SinanewsspiderPipeline': 300,
}
注意:上面大括号中的参数,一定要替换成 pipeline 中自己定义的 pipeline 类名,才能够进行激活并使用。
6. 运行爬虫
进入到爬虫项目根目录,运行爬虫,命令如下:scrapy crawl SinanewsSpider

爬虫运行过程中,会在控制台打印很多状态信息,是一个刷屏的过程,如果有错误的话,也会在控制台中显示出对应的错误信息,便于调试。

由于新闻数据太多,爬了1880条新闻(从上面的控制台中可以看到'item_scraped_count':1880)后,按 Ctrl + C 提前终止了运行, 在数据库中可以查看到所爬取的数据:


注意事项:
以下是本人在使用 Scrapy 爬虫过程中遇到的几个 Error,供大家参考:
1. 在 C/C++/Java 等语言中,代码块均放被到大括号中,但是,在 Python 中,使用缩进来表示代码块,如果碰到如下错误:
TabError: Inconsistent use of tabs and spaces in indentation

解决方法:
这个错误是说你用了 tab 键作缩进了,因为在 python 不像 C/C++ 里用大括号来区分程序块,而是用缩进,所以缩进很重要你把Tab都换成空格就好了。
2. 由于 Python2.x 和Python3.x 版本上的不兼容,导致 MySQLdb 暂时不支持 Python3,即出现如下错误时:
python3.*报"ImportError: No module named 'MySQLdb'"
解决方法:
MySQLdb只支持Python2.*,还不支持3.*
可以用PyMySQL代替。安装方法:pip install PyMySQL
然后在需要的项目中,把 __init__.py中添加两行:
import pymysql
pymysql.install_as_MySQLdb()
就可以用 import MySQLdb了。其他的方法与MySQLdb一样。
Python3 爬虫之 Scrapy 核心功能实现(二)的更多相关文章
- Python3 爬虫之 Scrapy 框架安装配置(一)
博客地址:http://www.moonxy.com 基于 Python 3.6.2 的 Scrapy 爬虫框架使用,Scrapy 的爬虫实现过程请参照本人的另一篇博客:Python3 爬虫之 Scr ...
- 小白学 Python 爬虫(34):爬虫框架 Scrapy 入门基础(二)
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 【Python3爬虫】Scrapy入门教程
Python版本:3.5 系统:Windows 一.准备工作 需要先安装几个库(pip,lxml,pywin32,Twisted,pyOpenSSL),这些都比较容易,如果使用的 ...
- 小白学 Python 爬虫(36):爬虫框架 Scrapy 入门基础(四) Downloader Middleware
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 小白学 Python 爬虫(37):爬虫框架 Scrapy 入门基础(五) Spider Middleware
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 小白学 Python 爬虫(35):爬虫框架 Scrapy 入门基础(三) Selector 选择器
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 小白学 Python 爬虫(38):爬虫框架 Scrapy 入门基础(六) Item Pipeline
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 小白学 Python 爬虫(40):爬虫框架 Scrapy 入门基础(七)对接 Selenium 实战
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 小白学 Python 爬虫(41):爬虫框架 Scrapy 入门基础(八)对接 Splash 实战
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
随机推荐
- Docker之- 使用Docker 镜像和仓库
目录 使用Docker 镜像和仓库 什么是 Docker 镜像 列出 Docker 镜像 tag 标签 Docker Hub 拉取镜像 查找镜像 构建镜像 创建Docker Hub 账号 使用 Doc ...
- 用友网络科技Java高级开发面试题(2019)
面试时间:2019年8月18日上午9:30 面试岗位:Java高级开发 面试形式:电话面试 这些天在boss上逛了下,看见北京Java开发工资比较诱人,便萌生了去北京的想法,做一名北漂的程序猿.约了几 ...
- Redis的高可用(HA)
本文参考 [https://www.jianshu.com/p/501c9c3b1b36] [https://www.jianshu.com/p/3b9054d3894b] 八大特性 1.速度快 正常 ...
- Django Mysql数据库-F查询和Q查询
一.F查询和Q查询 F查询: 在上面所有的例子中,我们构造的过滤器都只是将字段值与某个常量做比较.如果我们要对两个字段的值做比较,那该怎么做呢? Django 提供 F() 来做这样的比较.F() 的 ...
- python编辑已存在的excel坑: BadZipFile: File is not a zip file
背景-原代码如下,期望能自动创建excel,并且可以反复调用编辑: import xlwt,osfrom openpyxl.styles import Font, colors class Write ...
- Gradle——创建简单的项目
项目 & 任务 Gradle 的一切都是基于项目和任务的. 构建由一个或多个项目组成.项目的概念很抽象,它取决于你要用Gradle 做什么 .项目可以是 一个 Jar 库或者一个 web 程序 ...
- vuex详解vue简单使用
vue概念:vuex 是 Vue 配套的 公共数据管理工具,它可以把一些共享的数据,保存到 vuex 中,方便 整个程序中的任何组件直接获取或修改我们的公共数据: 配置vuex的步骤: 1.运行cnp ...
- HDU 2516
题意略. 思路: 典型的斐波那契博弈,这里说一下结论: 如果先手面对的n不是斐波那契数,那么先手必胜:否则后手胜. 详见代码: #include<bits/stdc++.h> using ...
- jq ajax传递json对象到服务端及contentType的用法
目录 0.一般情况下,通过键值对的方式将参数传递到服务端 1.ajax 传递复杂json对象到服务端 2.content-Type 对asp.net mvc项目的重要性 0.一般情况下,通过键值对的方 ...
- [Python] Scrapy爬虫框架入门
说明: 本文主要学习Scrapy框架入门,介绍如何使用Scrapy框架爬取页面信息. 项目案例:爬取腾讯招聘页面 https://hr.tencent.com/position.php?&st ...