持久化

步骤

pipeline/items
a. 先写pipeline类
class XXXPipeline(object):
def process_item(self, item, spider):
return item b. 写Item类
class XdbItem(scrapy.Item):
href = scrapy.Field()
title = scrapy.Field() c. 配置
ITEM_PIPELINES = {
'xdb.pipelines.XdbPipeline': 300,
} d. 爬虫,yield每执行一次,process_item就调用一次。 yield Item对象

编写pipeline

from scrapy.exceptions import DropItem

class FilePipeline(object):

	def __init__(self,path):
self.f = None
self.path = path @classmethod
def from_crawler(cls, crawler):
"""
初始化时候,用于创建pipeline对象
:param crawler:
:return:
"""
print('File.from_crawler')
path = crawler.settings.get('HREF_FILE_PATH')
return cls(path) def open_spider(self,spider):
"""
爬虫开始执行时,调用
:param spider:
:return:
"""
print('File.open_spider')
self.f = open(self.path,'a+') def process_item(self, item, spider):
# f = open('xx.log','a+')
# f.write(item['href']+'\n')
# f.close()
print('File',item['href'])
self.f.write(item['href']+'\n') # return item # 交给下一个pipeline的process_item方法
raise DropItem()# 后续的 pipeline的process_item方法不再执行 def close_spider(self,spider):
"""
爬虫关闭时,被调用
:param spider:
:return:
"""
print('File.close_spider')
self.f.close()

注意:pipeline是所有爬虫公用,如果想要给某个爬虫定制需要使用spider参数自己进行处理。 

去重规则

编写类

from scrapy.dupefilter import BaseDupeFilter
from scrapy.utils.request import request_fingerprint class XdbDupeFilter(BaseDupeFilter): def __init__(self):
self.visited_fd = set() @classmethod
def from_settings(cls, settings):
return cls() def request_seen(self, request):
fd = request_fingerprint(request=request)
if fd in self.visited_fd:
return True
self.visited_fd.add(fd) def open(self): # can return deferred
print('开始') def close(self, reason): # can return a deferred
print('结束') # def log(self, request, spider): # log that a request has been filtered
# print('日志')

配置  

# 修改默认的去重规则
# DUPEFILTER_CLASS = 'scrapy.dupefilter.RFPDupeFilter'
DUPEFILTER_CLASS = 'xdb.dupefilters.XdbDupeFilter'

爬虫使用 

class ChoutiSpider(scrapy.Spider):
name = 'chouti'
allowed_domains = ['chouti.com']
start_urls = ['https://dig.chouti.com/'] def parse(self, response):
print(response.request.url)
# item_list = response.xpath('//div[@id="content-list"]/div[@class="item"]')
# for item in item_list:
# text = item.xpath('.//a/text()').extract_first()
# href = item.xpath('.//a/@href').extract_first() page_list = response.xpath('//div[@id="dig_lcpage"]//a/@href').extract()
for page in page_list:
from scrapy.http import Request
page = "https://dig.chouti.com" + page
# yield Request(url=page,callback=self.parse,dont_filter=False) # https://dig.chouti.com/all/hot/recent/2
yield Request(url=page,callback=self.parse,dont_filter=True) # https://dig.chouti.com/all/hot/recent/2 

注意:
- request_seen中编写正确逻辑
- dont_filter=False

深度

配置文件:
# 限制深度
DEPTH_LIMIT = 3

cookie

方式一:
- 携带
Request(
url='https://dig.chouti.com/login',
method='POST',
body="phone=8613121758648&password=woshiniba&oneMonth=1",# # body=urlencode({})"phone=8615131255555&password=12sdf32sdf&oneMonth=1"
cookies=self.cookie_dict,
headers={
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
},
callback=self.check_login
) - 解析:
cookie_dict
cookie_jar = CookieJar()
cookie_jar.extract_cookies(response, response.request) # 去对象中将cookie解析到字典
for k, v in cookie_jar._cookies.items():
for i, j in v.items():
for m, n in j.items():
cookie_dict[m] = n.value

start_url

内部原理

scrapy引擎来爬虫中取起始URL:
1. 调用start_requests并获取返回值
2. v = iter(返回值)
3.
req1 = 执行 v.__next__()
req2 = 执行 v.__next__()
req3 = 执行 v.__next__()
...
4. req全部放到调度器中  

编写 

class ChoutiSpider(scrapy.Spider):
name = 'chouti'
allowed_domains = ['chouti.com']
start_urls = ['https://dig.chouti.com/']
cookie_dict = {} def start_requests(self):
# 方式一:
for url in self.start_urls:
yield Request(url=url)
# 方式二:
# req_list = []
# for url in self.start_urls:
# req_list.append(Request(url=url))
# return req_list 

定制:可以去redis获取 

深度和优先级

深度

- 最开始是0
- 每次yield时,会根据原来请求中的depth + 1
配置:DEPTH_LIMIT 深度控制

优先级

- 请求被下载的优先级 -= 深度 * 配置 DEPTH_PRIORITY
配置:DEPTH_PRIORITY

下载中间件

scrapy中设置代理

内置

在爬虫启动时,提前在os.envrion中设置代理即可。
class ChoutiSpider(scrapy.Spider):
name = 'chouti'
allowed_domains = ['chouti.com']
start_urls = ['https://dig.chouti.com/']
cookie_dict = {} def start_requests(self):
import os
os.environ['HTTPS_PROXY'] = "http://root:woshiniba@192.168.11.11:9999/"
os.environ['HTTP_PROXY'] = '19.11.2.32',
for url in self.start_urls:
yield Request(url=url,callback=self.parse)

meta(每次发请求都要自己携带)

class ChoutiSpider(scrapy.Spider):
name = 'chouti'
allowed_domains = ['chouti.com']
start_urls = ['https://dig.chouti.com/']
cookie_dict = {} def start_requests(self):
for url in self.start_urls:
yield Request(url=url,callback=self.parse,meta={'proxy':'"http://root:woshiniba@192.168.11.11:9999/"'})

自定义

import base64
import random
from six.moves.urllib.parse import unquote
try:
from urllib2 import _parse_proxy
except ImportError:
from urllib.request import _parse_proxy
from six.moves.urllib.parse import urlunparse
from scrapy.utils.python import to_bytes class XdbProxyMiddleware(object): def _basic_auth_header(self, username, password):
user_pass = to_bytes(
'%s:%s' % (unquote(username), unquote(password)),
encoding='latin-1')
return base64.b64encode(user_pass).strip() def process_request(self, request, spider):
PROXIES = [
"http://root:woshiniba@192.168.11.11:9999/",
"http://root:woshiniba@192.168.11.12:9999/",
"http://root:woshiniba@192.168.11.13:9999/",
"http://root:woshiniba@192.168.11.14:9999/",
"http://root:woshiniba@192.168.11.15:9999/",
"http://root:woshiniba@192.168.11.16:9999/",
]
url = random.choice(PROXIES) orig_type = ""
proxy_type, user, password, hostport = _parse_proxy(url)
proxy_url = urlunparse((proxy_type or orig_type, hostport, '', '', '', '')) if user:
creds = self._basic_auth_header(user, password)
else:
creds = None
request.meta['proxy'] = proxy_url
if creds:
request.headers['Proxy-Authorization'] = b'Basic ' + creds

scrapy框架 小知识的更多相关文章

  1. JS框架设计读书笔记之-小知识

    这一篇写一点小知识 JS中0.1+0.2为什么不等于0.3? 关于这个问题之前也很疑虑,老师也只是笼统的讲这是JS的语言问题,但是内部具体的情况却没有讲,看了书才发现原理如此简单. 简单来讲,计算机识 ...

  2. Python 爬取 北京市政府首都之窗信件列表-[Scrapy框架](2020年寒假小目标04)

    日期:2020.01.22 博客期:130 星期三 [代码说明,如果要使用此页代码,必须在本博客页面评论区给予说明] //博客总体说明 1.准备工作(本期博客) 2.爬取工作 3.数据处理 4.信息展 ...

  3. Scrapy框架简介及小项目应用

    今天来总结一下Scrapy框架的用法.scrapy的架构如下: Engine  :引擎,处理整个系统的数据流处理.触发事务,是整个框架的核心. Items :项目,它定义了爬取结果的数据结构,爬取的数 ...

  4. Scrapy框架爬虫

    一.sprapy爬虫框架 pip install pypiwin32 1) 创建爬虫框架 scrapy startproject Project # 创建爬虫项目 You can start your ...

  5. .NET面试题系列[1] - .NET框架基础知识(1)

    很明显,CLS是CTS的一个子集,而且是最小的子集. - 张子阳 .NET框架基础知识(1) 参考资料: http://www.tracefact.net/CLR-and-Framework/DotN ...

  6. HTML+CSS中的一些小知识

    今天分享一些HTML.CSS的小知识,希望能够对大家有所帮助! 1.解决网页乱码的问题:最重要的是要保证各个环节的字符编码一致! (1)编辑器的编辑环境的字符集(默认字符集):Crtl+U 常见的编码 ...

  7. Scrapy框架使用—quotesbot 项目(学习记录一)

    一.Scrapy框架的安装及相关理论知识的学习可以参考:http://www.yiibai.com/scrapy/scrapy_environment.html 二.重点记录我学习使用scrapy框架 ...

  8. Python爬虫从入门到放弃(十一)之 Scrapy框架整体的一个了解

    这里是通过爬取伯乐在线的全部文章为例子,让自己先对scrapy进行一个整理的理解 该例子中的详细代码会放到我的github地址:https://github.com/pythonsite/spider ...

  9. 安装scrapy框架的常见问题及其解决方法

    下面小编讲一下自己在windows10安装及配置Scrapy中遇到的一些坑及其解决的方法,现在总结如下,希望对大家有所帮助. 常见问题一:pip版本需要升级 如果你的pip版本比较老,可能在安装的过程 ...

随机推荐

  1. Charles 协助解决 metaweblog 排序问题

    Charles 是 http代理抓包工具,可有效用于手机客户端网络抓包,详见Charles安装说明.这里使用使用Charles的请求转发功能调试metaweblog的最近博文排序功能. 由于OpenL ...

  2. Excel不同工作簿之间提取信息

    Sub 不同工作簿间提取信息() '用于单个字段信息的提取: Dim w As Workbook, wb1 As Workbook, wb2 As Workbook, wb3 As Workbook ...

  3. 用活Firewalld防火墙之direct

    原文地址:http://www.excelib.com/article/294/show 学生在前面已经给大家介绍过了Firewalld中direct的作用,使用他可以直接使用iptables.ip6 ...

  4. java代码-----实现4个人打牌游戏的相关代码。线程

    总结:发送线程Sender().和接收线程Receiver() 虽然,这里的Sender()发送线程和Receiver()都有相同的睡眠时间,但是由于线程调度的不确定性,是的发送线程Sender每次发 ...

  5. java代码--实现随机输出10个随机数,并显示最大值,最小值

    总结;对于length()属性,还不是很熟悉.不会用它. package com.s.x; //随机产生10个随机数,并且显示出最大值,最小值 public class Love { public s ...

  6. PorterDuff.Mode

    参考:http://weishu.me/2015/09/23/Xfermode-in-android/ Sa = Source alphaDa = Dest alphaSc = Source colo ...

  7. (转)Docker volume plugin - enabled create local volume on docker host

    原文地址:https://hub.docker.com/r/cwspear/docker-local-persist-volume-plugin/ Short Description Create n ...

  8. jaxp使用笔记

    XML文件的解析技术有DOM和SAX方式,在Android中还有pull解析方式,这里不再讨论 DOM解析的方式和js中的DOM操作是一致的,DOM解析一次将文档加载入内存建立树型模型,但是如果XML ...

  9. apache 自定义404错误页面

    1.有些提供web服务的网站,在用户访问一个不存在的网站文件时,会提示404错误,如下所示: 现在要求自定义一个错误页面,也就是出现404错误代码时,跳转到我们自定义的网址上.下面记录下方法: 1.编 ...

  10. SlidingMenu Demo

    参考:http://www.krislq.com/2013/03/android_case_slidingmenu_fragment/ 我下载了它的例子,然后自己重写了一下,运行时总报错,原来是sup ...