Scrapy笔记02- 完整示例
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- 完整示例的更多相关文章
- springmvc 项目完整示例02 项目创建-eclipse创建动态web项目 配置文件 junit单元测试
包结构 所需要的jar包直接拷贝到lib目录下 然后选定 build path 之后开始写项目代码 配置文件 ApplicationContext.xml <?xml version=" ...
- 【原创】SpringBoot & SpringCloud 快速入门学习笔记(完整示例)
[原创]SpringBoot & SpringCloud 快速入门学习笔记(完整示例) 1月前在系统的学习SpringBoot和SpringCloud,同时整理了快速入门示例,方便能针对每个知 ...
- Scrapy笔记04- Selector详解
Scrapy笔记04- Selector详解 在你爬取网页的时候,最普遍的事情就是在页面源码中提取需要的数据,我们有几个库可以帮你完成这个任务: BeautifulSoup是python中一个非常流行 ...
- springmvc 项目完整示例06 日志–log4j 参数详细解析 log4j如何配置
Log4j由三个重要的组件构成: 日志信息的优先级 日志信息的输出目的地 日志信息的输出格式 日志信息的优先级从高到低有ERROR.WARN. INFO.DEBUG,分别用来指定这条日志信息的重要程度 ...
- Learning Scrapy笔记(六)- Scrapy处理JSON API和AJAX页面
摘要:介绍了使用Scrapy处理JSON API和AJAX页面的方法 有时候,你会发现你要爬取的页面并不存在HTML源码,譬如,在浏览器打开http://localhost:9312/static/, ...
- springmvc 项目完整示例01 需求与数据库表设计 简单的springmvc应用实例 web项目
一个简单的用户登录系统 用户有账号密码,登录ip,登录时间 打开登录页面,输入用户名密码 登录日志,可以记录登陆的时间,登陆的ip 成功登陆了的话,就更新用户的最后登入时间和ip,同时记录一条登录记录 ...
- springmvc 项目完整示例03 小结
利用spring 创建一个web项目 大致原理 利用spring的ioc 原理,例子中也就是体现在了配置文件中 设置了自动扫描注解 配置了数据库信息等 一般一个项目,主要有domain,dao,ser ...
- springmvc 项目完整示例04 整合mybatis mybatis所需要的jar包 mybatis配置文件 sql语句 mybatis应用
百度百科: MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBat ...
- springmvc 项目完整示例05 日志 --log4j整合 配置 log4j属性设置 log4j 配置文件 log4j应用
log4j 就是log for java嘛,老外都喜欢这样子,比如那个I18n ---internationalization 不就是i和n之间有18个字母... http://logging.a ...
随机推荐
- 基于canvas自动化运维工具
首先我们的工具绝对顶尖,绝对绚丽.如果有需要代码,可以加我微信索取.18500591275 前几天有个客户找到我,问我这个能不能做,我看自己也干了10年前端了,实在做不了,后来人家说给你10000你能 ...
- python2升级python3
需求: centos环境,python2.7需要升级为python3.x 1.请先手动(再次)安装 openssl .否则你升级之后,你的pip不能下载,会各种报错的. 比如这种错误: ImportE ...
- POJ 2249 暴力求组合数
Binomial Showdown Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 22692 Accepted: 692 ...
- 趣文:如何通过给MM修电脑培养感情[转]
在修之前,向 MM 反复声明,这电脑故障是有硬件和软件之分的,如果是硬件故障,例如显卡风扇不转了,显示器连线老化,显示器分辨率超出显示器指标,等等都会导致黑屏啊,这个我不回家用专门的工具是修不好的! ...
- 使用redis作为调度中心的celery时启动多个queue,报错Probably the key ('_kombu.binding.reply.celery.pidbox') has been removed from the Redis database
我今天在使用celery启动多个queue时遇到一个问题,当启动第二个queue是,第一个启动的queue日志报了下面一段错误 [2019-12-16 14:40:25,736: ERROR/Main ...
- 猫狗识别——PyTorch
猫狗识别 数据集下载: 网盘链接:https://pan.baidu.com/s/1SlNAPf3NbgPyf93XluM7Fg 提取密码:hpn4 1. 要导入的包 import os import ...
- vue基础之data
使用 调用data onLoad(option) { _self = this; _self.$data.xxxx = "te"; } 绑定节点 元素~~~~ <input ...
- Bootstrap4后台导航栏制作
<!Doctype html> <html lang="zh-cn"> <head> <!-- Required meta tags -- ...
- 默认展开ztree树形菜单
var setting = { view: { selectedMulti: false //按住ctrl是否可以多选 }, check: { enable: true , chkStyle: 'ch ...
- Qt中QWidget、QDialog和QMainWindow
QWidget 类是所有用户界面对象的基类.只有一个"页面" QMainWindow 是一个"窗口".含有菜单栏.状态栏.工具栏.停靠窗口.中心窗口 QDial ...