一、CrawlSpider模板

  • 创建项目
scrapy startproject 项目名称
  • 查看模板
scrapy genspider -l
  • 创建crawl模板
scrapy genspider -t crawl 爬虫名称 地址

二、Spider爬虫

# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
# 导入LinkExtractor用于提取链接
from scrapy.spiders import CrawlSpider, Rule
# Rule定义一个规则,然后让LinkExtractor取根据这些规则提取url from CrawlSpiderDemo.items import CrawlspiderdemoItem # 在scrapy框架中包了两个分类的爬虫分别是:Spider(基本爬虫)和CrawlSpider(增量模板爬虫)
# CrawlSpider是Spider的一个派生类,spider类设计原则只从start_urls列表中提取内容,CrawlSpider定义了一些规则,这些规则可以跟踪链接,从而可以使得一个页面中所有的符合规则的链接都被提取出来放入调度器中
# 在不断访问url的过程中,爬虫匹配到的url越来越多 class DushuSpider(CrawlSpider):
name = 'dushu'
allowed_domains = ['dushu.com']
start_urls = ['https://www.dushu.com/book/1002.html'] rules = (
Rule(LinkExtractor(allow=r'/book/1002_\d+\.html'), callback='parse_item', follow=True),
)
# rules 规则: 包含若干个Rule对象,每一个Rule对象对我们爬取网站的规则都做了一些特定的操作,根据LinkExtractor里面的规则提取出所有的链接,然后把这些链接通过引擎压入调度器的调度队列中,调度器进而去调度下载,然后回调parse_item (这里的回调方法写成了字符串形式) ,再从二次请求的这些url对应的页面中根据LinkExtractor的规则继续匹配(如果有重复,自动剔除),依次类推,直到匹配到所有的页面 # LinkExtractor的匹配规则:
# 用正则表达式来匹配:LinkExtractor(allow="某正则") # /book/1002_\d\.html
# 用xpath匹配:LinkExtractor(restrict_xpath="某xpath路径")
# 用css选择器:LinkExtractor(restrict_css="某css选择器") def parse_item(self, response):
print(response.url)
# 解析页面
book_list = response.xpath("//div[@class='bookslist']//li")
for book in book_list:
item = CrawlspiderdemoItem() item["book_name"] = book.xpath(".//h3/a/text()").extract_first() # 获取到二级页面的url
next_url = "https://www.dushu.com" + book.xpath(".//h3/a/@href").extract_first() yield scrapy.Request(url=next_url,callback=self.parse_next,meta={"item":item}) def parse_next(self, response):
item = response.meta["item"]
item["price"] = response.xpath("//span[@class='num']/text()").extract_first()
m = response.xpath("//div[@class='text txtsummary']")[2]
item["mulu"] = m.xpath(".//text()").extract() yield item

使用xpath或其他规则匹配下来的所有节点,返回的类型是列表类型

.extract()方法是提取它的内容

.extract_first()方法是提取列表第一个内容,若列表为空返回空,而不会报错

三、Ip代理设置

  • settings.py 设置
IPPOOL = [
{'ip':'113.16.160.101:8118'},
{'ip':'119.31.210.170:7777'},
{'ip':'183.129.207.83:10800'},
# {'ip':''},
# {'ip':''},
# {'ip':''},
# {'ip':''},
# {'ip':''},
] # 下载中间件设置
DOWNLOADER_MIDDLEWARES = {
'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware':123,
'IpAgent.middlewares.IPPOOLS': 125,
}

定义一个字段,表示我们收集好的代理

  • middlewares.py
# 从settings文件中导入IPPOOL
import random from .settings import IPPOOL
# 导入官方文档对应的HttpProxyMiddleware
from scrapy.contrib.downloadermiddleware.httpproxy import HttpProxyMiddleware # 创建一个代理中间件类集成自官方代理中间件
class IPPOOLS(HttpProxyMiddleware): # 重写初始化方法
def __init__(self,ip=''):
self.ip = ip # 重写请求处理方法
def process_request(self, request, spider):
# 从ip代理池中随机挑选一个ip地址
current_ip = random.choice(IPPOOL)
print('当前ip是:',current_ip['ip']) # 设置请求对象的代理服务器是当前ip
request.meta['proxy'] = 'https://' + current_ip['ip']
# 此时就可以把代理ip植入到下载器中

四、动态页面请求之selenium

  • settings.py设置
# 下载中间件设置
DOWNLOADER_MIDDLEWARES = {
'Toutiao.middlewares.ToutiaoDownloaderMiddleware': 543,
'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware':None,
}
  • middlewares.py设置
from scrapy import signals
from selenium import webdriver
from time import sleep from scrapy.http import HtmlResponse class ToutiaoDownloaderMiddleware(object):
# Not all methods need to be defined. If a method is not defined,
# scrapy acts as if the downloader middleware does not modify the
# passed objects. @classmethod
def from_crawler(cls, crawler):
# This method is used by Scrapy to create your spiders.
s = cls()
crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
return s def process_request(self, request, spider): # 创建一个webdriver对象
opt = webdriver.ChromeOptions()
opt.add_argument("--headless")
driver = webdriver.Chrome(options=opt)
driver.get(request.url)
sleep(3)
# 让页面滚动
js = "var q = document.documentElement.scrollTop=%d"
distance = 100
for i in range(100):
driver.execute_script(js%distance)
distance += 100
sleep(0.5)
body = driver.page_source
print("正在使用中间件下载...")
print("当前浏览器正在访问的网址是:",driver.current_url)
# 响应体需要重新定义
res = HtmlResponse(url=driver.current_url,body=body,encoding='utf-8',request=request) return res def process_response(self, request, response, spider):
# Called with the response returned from the downloader. # Must either;
# - return a Response object
# - return a Request object
# - or raise IgnoreRequest
return response def process_exception(self, request, exception, spider):
# Called when a download handler or a process_request()
# (from other downloader middleware) raises an exception. # Must either:
# - return None: continue processing this exception
# - return a Response object: stops process_exception() chain
# - return a Request object: stops process_exception() chain
pass def spider_opened(self, spider):
spider.logger.info('Spider opened: %s' % spider.name)

五、基本分布式爬虫部署redis储存

scrapy_redis组件

pip install scrapy_redis

1、scrapy和scrapy_redis的区别

    scrapy是一个通用的爬虫框架,不支持分布式

    scrapy_redis就是为实现scrapy的分布式而诞生的,它里面提功了redis的组件,通过这些redis组件,就可以实现分布式
2、部署分布式 服务器端(master端): 可以用某一台主机作为redis服务器的运行方(即服务端),也称为master 客户端(slaver端): 1)把普通爬虫修改成分布式,去掉start_urls(不让slaver随意的执行),替换成redis_key(为了让master能够控制slaver的爬去)
  • settings.py 设置

配置管道中间件

ITEM_PIPELINES = {
# 分布式的爬虫的数据可以不通过本地的管道(数据不需要往本地存),数据需要存在redis数据库中,在这里需要加入一个redis数据库的管道组件
"scrapy_redis.pipelines.RedisPipeline": 400
} # 指定Redis数据库相关配置
# Redis的主机地址
REDIS_HOST = "134.175.114.102"
# 端口号
REDIS_PORT = 6379
# 密码
# REDIS_PARAMS = {"password":'xxxx'} # 1、调度器需要切换成Scrapy_Redis的调度器(这个调度器是Scrapy_Redis组件对scrapy原生调度器的重写,加入一些分布式调度的算法)
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# 2、加入scrapy_redis的去重组件
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
# 3、爬取过程中是否允许暂停
SCHEDULER_PERSIST = True
  • spider设置
from scrapy_redis.spiders import RedisCrawlSpider

class ReadbookSpider(RedisCrawlSpider): # 注意继承RedisCrawlSpider
name = 'Readbook'
allowed_domains = ['www.dushu.com']
# start_urls = ['http://www.dushu.com/book/1002.html']
# start_urls = ['https://www.dushu.com/book/1002.html'] # 分布式的爬虫所有的url都是从redis数据库的相关键下面提取 # redis_key这个属性指定了分布式爬虫在获取url的时候从哪些键中获取的
redis_key = "dushu:start_urls" rules = (
Rule(LinkExtractor(allow=r'/book/1002_?\d*\.html'), callback='parse_item', follow=True),
)

小礼物走一走,来简书关注我

Scrapy框架之高级 转的更多相关文章

  1. python高级之scrapy框架

    目录: 爬虫性能原理 scrapy框架解析 一.爬虫性能原理 在编写爬虫时,性能的消耗主要在IO请求中,当单进程单线程模式下请求URL时必然会引起等待,从而使得请求整体变慢. 1.同步执行 impor ...

  2. 网络爬虫值scrapy框架基础

    简介 Scrapy是一个高级的Python爬虫框架,它不仅包含了爬虫的特性,还可以方便的将爬虫数据保存到csv.json等文件中. 首先我们安装Scrapy. 其可以应用在数据挖掘,信息处理或存储历史 ...

  3. Scrapy框架中选择器的用法【转】

    Python爬虫从入门到放弃(十四)之 Scrapy框架中选择器的用法 请给作者点赞 --> 原文链接 Scrapy提取数据有自己的一套机制,被称作选择器(selectors),通过特定的Xpa ...

  4. scrapy框架中选择器的用法

    scrapy框架中选择器的用法 Scrapy提取数据有自己的一套机制,被称作选择器(selectors),通过特定的Xpath或者CSS表达式来选择HTML文件的某个部分Xpath是专门在XML文件中 ...

  5. Python网咯爬虫 — Scrapy框架应用

    Scrapy框架       Scrapy是一个高级的爬虫框架,它不仅包括了爬虫的特征,还可以方便地将爬虫数据保存到CSV.Json等文件中.       Scrapy用途广泛,可以用于数据挖掘.监测 ...

  6. Scrapy——6 APP抓包—scrapy框架下载图片

    Scrapy——6 怎样进行APP抓包 scrapy框架抓取APP豆果美食数据 怎样用scrapy框架下载图片 怎样用scrapy框架去下载斗鱼APP的图片? Scrapy创建下载图片常见那些问题 怎 ...

  7. scrapy框架安装配置

    scrapy框架 scrapy安装(win) 1.pip insatll wheel 2.下载合适的版本的twisted:http://www.lfd.uci.edu/~gohlke/pythonli ...

  8. Scrapy框架的架构原理解析

    爬虫框架--Scrapy 如果你对爬虫的基础知识有了一定了解的话,那么是时候该了解一下爬虫框架了.那么为什么要使用爬虫框架? 学习框架的根本是学习一种编程思想,而不应该仅仅局限于是如何使用它.从了解到 ...

  9. Python爬虫Scrapy框架入门(2)

    本文是跟着大神博客,尝试从网站上爬一堆东西,一堆你懂得的东西 附上原创链接: http://www.cnblogs.com/qiyeboy/p/5428240.html 基本思路是,查看网页元素,填写 ...

随机推荐

  1. iOS UIBarButtonItem 固定尺寸

    自定义UIBarButtonItem的时候发现 有时候UIBarButtonItem尺寸会发生变化 通过以下方式可以很好的解决问题 [button.widthAnchor constraintEqua ...

  2. SpringMVC,SpringBoot上传文件简洁代码

    @RequestMapping("/updateAvatar.html") public String updateHeadUrl(MultipartFile avatar, Mo ...

  3. Go项目实战:打造高并发日志采集系统(四)

    前情回顾 前文我们完成了如下目标1 项目架构整体编写2 使框架支持热更新 本节目标 在前文的框架基础上,我们1 将之前实现的日志监控功能整合到框架中.2 一个日志对应一个监控协程,当配置热更新后根据新 ...

  4. C# AES的128位、192位、256位加密

    C# AES的128位.192位.256位加密   AES加密原理,这里就不解释了,自行百度.这里主要细说AES的CBC加密模式下的128位.192位.256位加密区别,参考 对称加密和分组加密中的四 ...

  5. uni-app 手指左右滑动实现翻页效果

    首先给页面添加 touch 事件 <view class="text-area" @touchstart="start" @touchend=" ...

  6. IDEA 2019中一些有偏好设置

    1.取消启动时自动进入上一次工程: 路径:Setting ——> Appearance & Behavior ——> System Setting 取消勾选Reopen last ...

  7. pagefile.sys 虚拟内存

    当我们使用电脑的时候,有时候需要更多的内存空间,但是内存条的价格又比较昂贵,我们可以用虚拟内存的方法,把一部分硬盘的空间作为内存使用. 进入控制面板---高级系统设置----高级-----更改---- ...

  8. LeetCode刷题2——颠倒二进制位

    一.题目要求 二.题目背景 此题依旧属于位运算范畴 知识点1:有符号和无符号二进制是怎样表现的? 对于有符号数,最高位为1说明是个负数 知识点2:进制之间的相互转换 (1)十进制转十六进制 hex(n ...

  9. 【并行计算-CUDA开发】浅谈GPU并行计算新趋势

    随着GPU的可编程性不断增强,GPU的应用能力已经远远超出了图形渲染任务,利用GPU完成通用计算的研究逐渐活跃起来,将GPU用于图形渲染以外领域的计算成为GPGPU(General Purpose c ...

  10. 多线程基础知识---sleep和wait区别

    1.sleep()是Thread类的静态方法:wait()是Object的成员方法 2.sleep()可以在任何地方使用;wait()只能在同步方法或代码块中使用