Scrapy笔记02- 完整示例

这篇文章我们通过一个比较完整的例子来教你使用Scrapy,我选择爬取虎嗅网首页的新闻列表。

这里我们将完成如下几个步骤:

  • 创建一个新的Scrapy工程
  • 定义你所需要要抽取的Item对象
  • 编写一个spider来爬取某个网站并提取出所有的Item对象
  • 编写一个Item Pipline来存储提取出来的Item对象

Scrapy使用Python语言编写,如果你对这门语言还不熟,请先去学习下基本知识。

创建Scrapy工程

在任何你喜欢的目录执行如下命令

scrapy startproject coolscrapy

将会创建coolscrapy文件夹,其目录结构如下:

coolscrapy/
scrapy.cfg # 部署配置文件 coolscrapy/ # Python模块,你所有的代码都放这里面
__init__.py items.py # Item定义文件 pipelines.py # pipelines定义文件 settings.py # 配置文件 spiders/ # 所有爬虫spider都放这个文件夹下面
__init__.py
...

定义我们的Item

我们通过创建一个scrapy.Item类,并定义它的类型为scrapy.Field的属性, 我们准备将虎嗅网新闻列表的名称、链接地址和摘要爬取下来。

import scrapy

class HuxiuItem(scrapy.Item):
title = scrapy.Field() # 标题
link = scrapy.Field() # 链接
desc = scrapy.Field() # 简述
posttime = scrapy.Field() # 发布时间

第一个Spider

  也许你觉得定义这个Item有点麻烦,但是定义完之后你可以得到许多好处,这样你就可以使用Scrapy中其他有用的组件和帮助类。

蜘蛛就是你定义的一些类,Scrapy使用它们来从一个domain(或domain组)爬取信息。 在蜘蛛类中定义了一个初始化的URL下载列表,以及怎样跟踪链接,如何解析页面内容来提取Item。

  定义一个Spider,只需继承scrapy.Spider类并定于一些属性:

  • name: Spider名称,必须是唯一的
  • start_urls: 初始化下载链接URL
  • parse(): 用来解析下载后的Response对象,该对象也是这个方法的唯一参数。 它负责解析返回页面数据并提取出相应的Item(返回Item对象),还有其他合法的链接URL(返回Request对象)。

  我们在coolscrapy/spiders文件夹下面新建huxiu_spider.py,内容如下:

  huxiu_spider.py

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""
Topic: sample
Desc :
"""
from coolscrapy.items import HuxiuItem
import scrapy class HuxiuSpider(scrapy.Spider):
name = "huxiu"
allowed_domains = ["huxiu.com"]
start_urls = [
"http://www.huxiu.com/index.php"
] def parse(self, response):
for sel in response.xpath('//div[@class="mod-info-flow"]/div/div[@class="mob-ctt"]'):
item = HuxiuItem()
item['title'] = sel.xpath('h3/a/text()')[0].extract()
item['link'] = sel.xpath('h3/a/@href')[0].extract()
url = response.urljoin(item['link'])
item['desc'] = sel.xpath('div[@class="mob-sub"]/text()')[0].extract()
print(item['title'],item['link'],item['desc'])

运行爬虫

在根目录执行下面的命令,其中huxiu是你定义的spider名字:

scrapy crawl huxiu

如果一切正常,应该可以打印出每一个新闻

处理链接

如果想继续跟踪每个新闻链接进去,看看它的详细内容的话,那么可以在parse()方法中返回一个Request对象, 然后注册一个回调函数来解析新闻详情。

from coolscrapy.items import HuxiuItem
import scrapy class HuxiuSpider(scrapy.Spider):
name = "huxiu"
allowed_domains = ["huxiu.com"]
start_urls = [
"http://www.huxiu.com/index.php"
] def parse(self, response):
for sel in response.xpath('//div[@class="mod-info-flow"]/div/div[@class="mob-ctt"]'):
item = HuxiuItem()
item['title'] = sel.xpath('h3/a/text()')[0].extract()
item['link'] = sel.xpath('h3/a/@href')[0].extract()
url = response.urljoin(item['link'])
item['desc'] = sel.xpath('div[@class="mob-sub"]/text()')[0].extract()
# print(item['title'],item['link'],item['desc'])
yield scrapy.Request(url, callback=self.parse_article) def parse_article(self, response):
detail = response.xpath('//div[@class="article-wrap"]')
item = HuxiuItem()
item['title'] = detail.xpath('h1/text()')[0].extract()
item['link'] = response.url
item['posttime'] = detail.xpath(
'div[@class="article-author"]/span[@class="article-time"]/text()')[0].extract()
print(item['title'],item['link'],item['posttime'])
yield item

现在parse只提取感兴趣的链接,然后将链接内容解析交给另外的方法去处理了。 你可以基于这个构建更加复杂的爬虫程序了。

导出抓取数据

最简单的保存抓取数据的方式是使用json格式的文件保存在本地,像下面这样运行:

scrapy crawl huxiu -o items.json

在演示的小系统里面这种方式足够了。不过如果你要构建复杂的爬虫系统, 最好自己编写Item Pipeline

保存数据到数据库

上面我们介绍了可以将抓取的Item导出为json格式的文件,不过最常见的做法还是编写Pipeline将其存储到数据库中。 我们在coolscrapy/pipelines.py定义

# -*- coding: utf-8 -*-
import datetime
import redis
import json
import logging
from contextlib import contextmanager from scrapy import signals
from scrapy.exporters import JsonItemExporter
from scrapy.pipelines.images import ImagesPipeline
from scrapy.exceptions import DropItem
from sqlalchemy.orm import sessionmaker
from coolscrapy.models import News, db_connect, create_news_table, Article class ArticleDataBasePipeline(object):
"""保存文章到数据库""" def __init__(self):
engine = db_connect()
create_news_table(engine)
self.Session = sessionmaker(bind=engine) def open_spider(self, spider):
"""This method is called when the spider is opened."""
pass def process_item(self, item, spider):
a = Article(url=item["url"],
title=item["title"].encode("utf-8"),
publish_time=item["publish_time"].encode("utf-8"),
body=item["body"].encode("utf-8"),
source_site=item["source_site"].encode("utf-8"))
with session_scope(self.Session) as session:
session.add(a) def close_spider(self, spider):
pass

上面我使用了python中的SQLAlchemy来保存数据库,这个是一个非常优秀的ORM库, 我写了篇关于它的入门教程,可以参考下。

然后在setting.py中配置这个Pipeline,还有数据库链接等信息:

ITEM_PIPELINES = {
'coolscrapy.pipelines.ArticleDataBasePipeline': 5,
} # linux pip install MySQL-python
DATABASE = {'drivername': 'mysql',
'host': '192.168.203.95',
'port': '',
'username': 'root',
'password': 'mysql',
'database': 'spider',
'query': {'charset': 'utf8'}}

再次运行爬虫

scrapy crawl huxiu

那么所有新闻的文章都存储到数据库中去了。

Scrapy笔记02- 完整示例的更多相关文章

  1. springmvc 项目完整示例02 项目创建-eclipse创建动态web项目 配置文件 junit单元测试

    包结构 所需要的jar包直接拷贝到lib目录下 然后选定 build path 之后开始写项目代码 配置文件 ApplicationContext.xml <?xml version=" ...

  2. 【原创】SpringBoot & SpringCloud 快速入门学习笔记(完整示例)

    [原创]SpringBoot & SpringCloud 快速入门学习笔记(完整示例) 1月前在系统的学习SpringBoot和SpringCloud,同时整理了快速入门示例,方便能针对每个知 ...

  3. Scrapy笔记04- Selector详解

    Scrapy笔记04- Selector详解 在你爬取网页的时候,最普遍的事情就是在页面源码中提取需要的数据,我们有几个库可以帮你完成这个任务: BeautifulSoup是python中一个非常流行 ...

  4. springmvc 项目完整示例06 日志–log4j 参数详细解析 log4j如何配置

    Log4j由三个重要的组件构成: 日志信息的优先级 日志信息的输出目的地 日志信息的输出格式 日志信息的优先级从高到低有ERROR.WARN. INFO.DEBUG,分别用来指定这条日志信息的重要程度 ...

  5. Learning Scrapy笔记(六)- Scrapy处理JSON API和AJAX页面

    摘要:介绍了使用Scrapy处理JSON API和AJAX页面的方法 有时候,你会发现你要爬取的页面并不存在HTML源码,譬如,在浏览器打开http://localhost:9312/static/, ...

  6. springmvc 项目完整示例01 需求与数据库表设计 简单的springmvc应用实例 web项目

    一个简单的用户登录系统 用户有账号密码,登录ip,登录时间 打开登录页面,输入用户名密码 登录日志,可以记录登陆的时间,登陆的ip 成功登陆了的话,就更新用户的最后登入时间和ip,同时记录一条登录记录 ...

  7. springmvc 项目完整示例03 小结

    利用spring 创建一个web项目 大致原理 利用spring的ioc 原理,例子中也就是体现在了配置文件中 设置了自动扫描注解 配置了数据库信息等 一般一个项目,主要有domain,dao,ser ...

  8. springmvc 项目完整示例04 整合mybatis mybatis所需要的jar包 mybatis配置文件 sql语句 mybatis应用

    百度百科: MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBat ...

  9. springmvc 项目完整示例05 日志 --log4j整合 配置 log4j属性设置 log4j 配置文件 log4j应用

    log4j 就是log for java嘛,老外都喜欢这样子,比如那个I18n  ---internationalization  不就是i和n之间有18个字母... http://logging.a ...

随机推荐

  1. Visual Studio 调试系列8 查找导致程序崩溃的 DLL(使用模块窗口)

    系列目录     [已更新最新开发文章,点击查看详细] 如果应用程序在调用系统 DLL 或他人的代码时崩溃,则需要找出在崩溃发生时处于活动状态的 DLL. 如果在自己的程序之外的 DLL 中遇到崩溃, ...

  2. 【网络知识之二】HTTP协议

    HTTP协议(Hypertext Transfer Protocol,超文本传输协议),一种无状态的.应用层的.以请求/应答方式运行的协议,它使用可扩展的语义和自描述消息格式,与基于网络的超文本信息系 ...

  3. [转帖]PG的时间函数使用整理如下

    PG的时间函数使用整理如下 https://blog.csdn.net/dahuzix/article/details/48576945 1.获取系统时间函数 -- :: -- :: -- :: 2. ...

  4. 【题解】NOIP2015提高组 复赛

    [题解]NOIP2015提高组 复赛 传送门: 神奇的幻方 \([P2615]\) 信息传递 \([P2661]\) 斗地主 \([P2668]\) 跳石头 \([P2678]\) 子串 \([P26 ...

  5. mini Redis(项目 二)

    一个仿Redis的内存数据库(主要用来做命令解析)服务端,  客户端使用的开源工具 : https://dom4j.github.io/     github:https://github.com/h ...

  6. win10家庭版添加本地策略

      在桌面新建一个空文件夹(此处是需要新建文件夹而并非文件),文件夹的名称大家随意即可.如下图所示:   打开刚刚新建的文件夹(双击文件夹则打开文件夹).如下图所示:   在刚刚我们打开的文件夹资源地 ...

  7. ELK + kafka 分布式日志解决方案

    概述 本文介绍使用ELK(elasticsearch.logstash.kibana) + kafka来搭建一个日志系统.主要演示使用spring aop进行日志收集,然后通过kafka将日志发送给l ...

  8. 微服务架构 ------ 插曲 Mybatis逆向工程

    1.首先是pom.xml, 我们需要引入需要的mvn插件 <?xml version="1.0" encoding="UTF-8"?> <pr ...

  9. JAVA集合框架的特点及实现原理简介

    1.集合框架总体架构 集合大致分为Set.List.Queue.Map四种体系,其中List,Set,Queue继承自Collection接口,Map为独立接口 Set的实现类有:HashSet,Li ...

  10. Jenkins 显示语言-英文切换中文

    1.进入插件管理 搜索 Locale 插件并进行安装 2.插件安装成功后进入系统设置 3.在 Locale 中 Default Language 字段填入 zh_CN 并且勾选 Ignore brow ...