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. 【07月16日】A股滚动市净率PB历史新低排名

    2010年01月01日 到 2019年07月16日 之间,滚动市净率历史新低排名. 上市三年以上的公司,2019年07月16日市净率在30以下的公司. 来源:A股滚动市净率(PB)历史新低排名. 1 ...

  2. SIFT提取特征

    SIFT特征提取: 角点检测: Morvavec角点检测算子:基于灰度方差的角点检测方法,该算子计算图像中某个像素点沿水平.垂直方向上的灰度差异,以确定角点位置 Harris角点检测算子:不止考察水平 ...

  3. 图解微信小程序---获取电影列表

    图解微信小程序---获取电影列表 代码笔记 list跳转 第一步:编写前端页面获取相关的电影列表参数(对于显示参数不熟悉,可以先写js,通过console  Log的方式获取我们电影的相关数据字段,后 ...

  4. KVM 学习笔记

    查看虚拟化环境 (1)查看虚拟机环境 (2)查看kvm模块支持 (3)查看虚拟工具版本 (4)查看网桥

  5. babel plugin和presets是什么,怎么用?

    https://www.fullstackreact.com/articles/what-are-babel-plugins-and-presets/ 当开发react或者vuejs app时,开发者 ...

  6. golang-Json编码解码

    目录 一. 类型映射 二. 输出控制 三. 类型编码 四. 类型解码 五. 输出重写 六. 扩展功能 七. Bson编码 在线工具:https://www.json.cn 一. 类型映射 golang ...

  7. 基于vue+springboot+docker网站搭建【四】安装nginx

    安装nginx 搜索镜像:systemctl search nginx 下载镜像(注意带上版本):docker pull nginx:1.10 查看自己机器的所有镜像:docker images 启动 ...

  8. 内部类不能有静态变量(除静态的对Static的理解)

    关于内部类(static与final) Static 不用实例化就能加载进内存 而内部类需要外部类实例化后才能加载进内存.这就间接造成static需要实例化了.与static不需要实例化语义矛盾 1. ...

  9. web的应用模式

    在开发web应用中,有两种模式: 1.前后端分离. 2.前后端不分离. 一.前后端不分离 在前后端不分离的应用模式中,前端页面看到的效果是有后端控制的,由后端渲染页面或重定向,也就是后端需要控制前端的 ...

  10. riscv 汇编与反汇编

    为了riscv指令集,我们需要汇编与反汇编工具来分析指令格式. 可以用下面的两个工具来汇编和反汇编,下载链接:https://pan.baidu.com/s/1eUbBlVc riscv-none-e ...