python Scrapy 从零开始学习笔记(二)
在之前的文章中我们简单了解了一下Scrapy 框架和安装及目录的介绍,本章我们将根据 scrapy 框架实现博客园首页博客的爬取及数据处理。
我们先在自定义的目录中通过命令行来构建一个 scrapy 项目目录
scrapy startproject scrapyCnblogs
生成一下目录:
然后在终端命令行中输入
scrapy genspider cnblogs cnblogs.com
在 scrapCnblogs/spiders 下就会生成一个 cnblogs.py 的文件,代码如下:
# -*- coding: utf-8 -*-
import scrapy class CnblogsSpider(scrapy.Spider):
name = 'cnblogs'
allowed_domains = ['cnblogs.com']
start_urls = ['http://cnblogs.com/'] def parse(self, response):
pass
在上面的代码中 allowed_domains 将限制爬虫的作用范围,start_urls 是爬虫的起始 url,爬取的结果将在 parse 方法中进行数据处理。
我们要做的案例是爬取博客园首页的博客列表,链接为 https://www.cnblogs.com/,内容如下:
本次我们就只爬取网页中间的博客列表中的:博客名称,链接和作者 这三个信息,分别定义为 title,link,author。
在页面筛选信息时我用的是我比较习惯用的 xpath,scrapy 框架集成了该模块,使用起来也非常方便。xpath 的使用规则:https://www.cnblogs.com/weijiutao/p/10879871.html
我们先通过控制台来查找到我们要获取的字段信息:
我们根据xpath获取到的信息将上面的 cnblogs.py 文件改为如下:
# -*- coding: utf-8 -*-
import scrapy # 创建一个爬虫类
class CnblogsSpider(scrapy.Spider):
# 爬虫名
name = 'cnblogs'
# 允许爬虫作用的范围
allowed_domains = ['cnblogs.com']
# 爬虫起始的url
start_urls = ['https://www.cnblogs.com'] def parse(self, response):
# 通过 scrapy 自带的xpath匹配出所有博客的根结点列表集合
post_list = response.xpath("//div[@class='post_item_body']")
# 遍历根节点集合
for post in post_list:
# extract() 将匹配的对象结果转换为Unicode字符串,不加 extract() 结果为xpath匹配对象
# title
title = post.xpath("./h3/a[@class='titlelnk']/text()").extract()[0]
# link
link = post.xpath("./h3/a[@class='titlelnk']/@href").extract()[0]
# author
author = post.xpath("./div[@class='post_item_foot']/a/text()").extract()[0]
print(title + link + author)
上面的代码中,我们只需要定义 allowed_domains 和 start_urls 这两个字段,scrapy 就会自动帮我们去进行内容爬取来,并且通过 parse() 方法返回 response 的结果,然后我们再通过 scrapy 提供的 xpath 模块过滤我们想要的信息就可以了。
在终端输出:
scrapy crawl cnblogs
其中 cnblogs 使我们在上面的代码中定义的爬虫名 name 的值,意思是启动该爬虫,然后我们就可以在控制台查看我们的打印结果了:
上面的代码已经大大简化了我们很久之前写的爬虫的文章,接下来我们再来将 scrapy 其他的文件串联起来。
在 scrapyCnblogs/items.py 中写入一下代码:
# -*- coding: utf-8 -*- # Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html import scrapy class ScrapycnblogsItem(scrapy.Item):
# define the fields for your item here like:
# 标题
title = scrapy.Field()
# 链接
link = scrapy.Field()
# 作者
author = scrapy.Field()
该代码是将我们想要过滤的信息进行定义,我们在此文件中定义了一个 ScrapycnblogsItem 的类,里面定义了 title,link 和 author 三个字段。
接下来将刚才写的 cnblogs.py 改为如下代码:
# -*- coding: utf-8 -*-
import scrapy
# 引入 ScrapycnblogsItem 类
from scrapyCnblogs.items import ScrapycnblogsItem # 创建一个爬虫类
class CnblogsSpider(scrapy.Spider):
# 爬虫名
name = 'cnblogs'
# 允许爬虫作用的范围
allowed_domains = ['cnblogs.com']
# 爬虫起始的url
start_urls = ['https://www.cnblogs.com'] def parse(self, response):
# 通过 scrapy 自带的xpath匹配出所有博客的根结点列表集合
post_list = response.xpath("//div[@class='post_item_body']")
# 遍历根节点集合
for post in post_list:
# extract() 将匹配的对象结果转换为Unicode字符串,不加 extract() 结果为xpath匹配对象
# title
title = post.xpath("./h3/a[@class='titlelnk']/text()").extract()[0]
# link
link = post.xpath("./h3/a[@class='titlelnk']/@href").extract()[0]
# author
author = post.xpath("./div[@class='post_item_foot']/a/text()").extract()[0] # 将我们得到的数据封装到一个 `ScrapycnblogsItem` 对象
item = ScrapycnblogsItem()
item['title'] = title
item['link'] = link
item['author'] = author # 将获取的数据交给pipelines
yield item
在上面的代码中,我们引入了刚刚定义的 ScrapycnblogsItem 类,然后将爬取过滤的信息复制给 item ,最后 yield 出去,这里所做的操作会将我们的信息交给 scrapyCnblogs/pipelines.py 文件,接下来我们就只需要在 pipelines.py 文件中对我们的数据进行操作就可以了。
pipelines.py 代码如下:
# -*- coding: utf-8 -*- # Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html import json class ScrapycnblogsPipeline(object):
# __init__ 方法是可选的,作为类的初始化方法
def __init__(self):
self.filename = open('cnblogs.json', 'w') # process_item 方法是必须写的,用来处理item数据
def process_item(self, item, spider):
text = json.dumps(dict(item), ensure_ascii=False) + ',\n'
self.filename.write(text.encode('utf-8'))
return item # close_spider 方法是可选的,结束时调用这个方法
def close_spider(self, spider):
self.filename.close()
在上面的代码中 ScrapycnblogsPipeline 类中的 process_item() 方法就会接收到 cnblogs.py 所返回的 item 信息,我们在 process_item() 方法中将所获取的 item 写入到了一个 cnblogs.json 的文件中。
最后还需要做的一步就是去 scrapyCnblogs/settings.py 文件中放开我们定义的这个管道文件了。
settings.py 代码如下:
# -*- coding: utf-8 -*- # Scrapy settings for scrapyCnblogs project
#
# For simplicity, this file contains only settings considered important or
# commonly used. You can find more settings consulting the documentation:
#
# https://docs.scrapy.org/en/latest/topics/settings.html
# https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
# https://docs.scrapy.org/en/latest/topics/spider-middleware.html BOT_NAME = 'scrapyCnblogs' SPIDER_MODULES = ['scrapyCnblogs.spiders']
NEWSPIDER_MODULE = 'scrapyCnblogs.spiders' # Crawl responsibly by identifying yourself (and your website) on the user-agent
# USER_AGENT = 'scrapyCnblogs (+http://www.yourdomain.com)' # Obey robots.txt rules
ROBOTSTXT_OBEY = True # Configure maximum concurrent requests performed by Scrapy (default: 16)
# CONCURRENT_REQUESTS = 32 # Configure a delay for requests for the same website (default: 0)
# See https://docs.scrapy.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs
# 延迟 3 秒获取信息
DOWNLOAD_DELAY = 3
# The download delay setting will honor only one of:
# CONCURRENT_REQUESTS_PER_DOMAIN = 16
# CONCURRENT_REQUESTS_PER_IP = 16 # Disable cookies (enabled by default)
# COOKIES_ENABLED = False # Disable Telnet Console (enabled by default)
# TELNETCONSOLE_ENABLED = False # Override the default request headers:
# 定义报头信息
DEFAULT_REQUEST_HEADERS = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en',
} # Enable or disable spider middlewares
# See https://docs.scrapy.org/en/latest/topics/spider-middleware.html
# SPIDER_MIDDLEWARES = {
# 'scrapyCnblogs.middlewares.ScrapycnblogsSpiderMiddleware': 543,
# } # Enable or disable downloader middlewares
# See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
# DOWNLOADER_MIDDLEWARES = {
# 'scrapyCnblogs.middlewares.ScrapycnblogsDownloaderMiddleware': 543,
# } # Enable or disable extensions
# See https://docs.scrapy.org/en/latest/topics/extensions.html
# EXTENSIONS = {
# 'scrapy.extensions.telnet.TelnetConsole': None,
# } # Configure item pipelines
# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
# 管道文件
ITEM_PIPELINES = {
'scrapyCnblogs.pipelines.ScrapycnblogsPipeline': 300, # 优先级,越小优先级越高
} # Enable and configure the AutoThrottle extension (disabled by default)
# See https://docs.scrapy.org/en/latest/topics/autothrottle.html
# AUTOTHROTTLE_ENABLED = True
# The initial download delay
# AUTOTHROTTLE_START_DELAY = 5
# The maximum download delay to be set in case of high latencies
# AUTOTHROTTLE_MAX_DELAY = 60
# The average number of requests Scrapy should be sending in parallel to
# each remote server
# AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0
# Enable showing throttling stats for every response received:
# AUTOTHROTTLE_DEBUG = False # Enable and configure HTTP caching (disabled by default)
# See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings
# HTTPCACHE_ENABLED = True
# HTTPCACHE_EXPIRATION_SECS = 0
# HTTPCACHE_DIR = 'httpcache'
# HTTPCACHE_IGNORE_HTTP_CODES = []
# HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'
在上面的代码第 70 行,我们就设置了 ScrapycnblogsPipelines 类的管道,同时还设置了一下延迟时间和报头信息,延迟时间如果不设置的话经常访问可能会被对方发现察觉而封IP,在爬取多页面信息的时候也有助于上次信息处理成功后再处理下次请求,避免数据不完整,报头信息是模拟浏览器的信息,都是为了增加我们的信息爬取成功率。
最后我们在终端输入:
scrapy crawl cnblogs
在我们的目录下就会生成一个 cnblogs.json 的文件,如下:
至此我们就完成了一个相对完整的基于 scrapy 框架爬取博客园首页博客列表的爬虫了!
python Scrapy 从零开始学习笔记(二)的更多相关文章
- python Scrapy 从零开始学习笔记(一)
在之前我做了一个系列的关于 python 爬虫的文章,传送门:https://www.cnblogs.com/weijiutao/p/10735455.html,并写了几个爬取相关网站并提取有效信息的 ...
- Python scrapy爬虫学习笔记01
1.scrapy 新建项目 scrapy startproject 项目名称 2.spiders编写(以爬取163北京新闻为例) 此例中用到了scrapy的Itemloader机制,itemloade ...
- oracle从零开始学习笔记 二
多表查询 等值连接(Equijoin) select ename,empno,sal,emp.deptno from emp,dept where dept.deptno=emp.deptno; 非等 ...
- python3.4学习笔记(二十六) Python 输出json到文件,让json.dumps输出中文 实例代码
python3.4学习笔记(二十六) Python 输出json到文件,让json.dumps输出中文 实例代码 python的json.dumps方法默认会输出成这种格式"\u535a\u ...
- python3.4学习笔记(二十五) Python 调用mysql redis实例代码
python3.4学习笔记(二十五) Python 调用mysql redis实例代码 #coding: utf-8 __author__ = 'zdz8207' #python2.7 import ...
- python3.4学习笔记(二十四) Python pycharm window安装redis MySQL-python相关方法
python3.4学习笔记(二十四) Python pycharm window安装redis MySQL-python相关方法window安装redis,下载Redis的压缩包https://git ...
- python3.4学习笔记(二十三) Python调用淘宝IP库获取IP归属地返回省市运营商实例代码
python3.4学习笔记(二十三) Python调用淘宝IP库获取IP归属地返回省市运营商实例代码 淘宝IP地址库 http://ip.taobao.com/目前提供的服务包括:1. 根据用户提供的 ...
- python3.4学习笔记(二十二) python 在字符串里面插入指定分割符,将list中的字符转为数字
python3.4学习笔记(二十二) python 在字符串里面插入指定分割符,将list中的字符转为数字在字符串里面插入指定分割符的方法,先把字符串变成list然后用join方法变成字符串str=' ...
- python3.4学习笔记(二十一) python实现指定字符串补全空格、前面填充0的方法
python3.4学习笔记(二十一) python实现指定字符串补全空格.前面填充0的方法 Python zfill()方法返回指定长度的字符串,原字符串右对齐,前面填充0.zfill()方法语法:s ...
随机推荐
- 全栈的自我修养: 001环境搭建 (使用Vue,Spring Boot,Flask,Django 完成Vue前后端分离开发)
全栈的自我修养: 环境搭建 Not all those who wander are lost. 彷徨者并非都迷失方向. Table of Contents @ 目录 前言 环境准备 nodejs v ...
- 去除List集合中的重复值(四种好用的方法)(基本数据类型可用)
最近项目中需要对list集合中的重复值进行处理,大部分是采用两种方法,一种是用遍历list集合判断后赋给另一个list集合,一种是用赋给set集合再返回给list集合. 但是赋给set集合后,由于se ...
- 云服务器解析域名去掉Tomcat的8080端口号显示
- HTTP 协议详解(二)
前面一篇已经说过了 HTTP 的基本特性,HTTP 的发展史,前情回顾.这一篇就更详细的 HTTP 协议使用过程一些参数配置,缓存,Cookie设置相关的细节做一些梳理. 数据类型与编码 在 TCP/ ...
- Buffer的创建及使用源码分析——ByteBuffer为例
目录 Buffer概述 Buffer的创建 Buffer的使用 总结 参考资料 Buffer概述 注:全文以ByteBuffer类为例说明 在Java中提供了7种类型的Buffer,每一种类型的Buf ...
- 面试必杀技,讲一讲Spring中的循环依赖
本系列文章: 听说你还没学Spring就被源码编译劝退了?30+张图带你玩转Spring编译 读源码,我们可以从第一行读起 你知道Spring是怎么解析配置类的吗? 配置类为什么要添加@Configu ...
- P1004 方格取数——奇怪的dp
P1004 方格取数 题目描述 设有 \(N\times N\) 的方格图 \((N\leq 20)\),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字 \(0\) .如下图所示(见样例) ...
- Java数组的定义与使用
一.数组概念 可以将多个同一数据类型的数据,存储到同一个容器中 1. 格式 数据类型[] 数组名=new 数据类型[元素个数] "数据类型"表示该数组中可以存放哪一类型的数据 &q ...
- day48 work
1 navicat自己玩一玩 2 练习题一定要搞懂 照着我的思路一遍遍的看敲 3 熟悉pymysql的使用 4 sql注入产生的原因和解决方法 了解 5 思考:如何结合mysql实现用户的注册和登录功 ...
- MobileNetV1/V2/V3简述 | 轻量级网络
MobileNet系列很重要的轻量级网络家族,出自谷歌,MobileNetV1使用深度可分离卷积来构建轻量级网络,MobileNetV2提出创新的inverted residual with line ...