今日内容:
1.高性能相关
2.scrapy框架

内容详细:
1. 高性能爬虫相关:
- 提高并发方案 :多进程->多线程->单线程

- 本质:
sk = socket.socket()
# 连接的过程是 阻塞
sk.connect(('www.cnblogs.com',80))
sk.sendall(b'GET /wupeiqi http1.1\r\n......\r\n\r\n')
sk.sendall(b'POST /wupeiqi http1.1\r\n......\r\n\r\nuser=leo&pwd=123')

# 阻塞
data = sk.recv(8096)

sk.cloes()

- 阻塞

***** 第一次连接 www.baidu.com 成功后 发送请求,接收请求,关闭连接 再开始第二次访问www.cnblogs.com
***** 如果有一个线程一直处理连接,成功之后就返回 谁先返回就执行谁 比如三个url依次进入 connect 处于阻塞 谁先回来就谁往下走,
***** 比如cnblogs先回来了 往下走 但是到recv遇见阻塞了,这个时候baidu回来了 再让他往下走 相当于一个线程遇到阻塞 就去干其他的事
***** 1、socket非阻塞 2、监听其他socket的状态

import socket
def task(url):
sk = socket.socket()
# 连接的过程是 阻塞
sk.connect((url,80))
# HTTP协议 请求头和请求体之间\r\n\r\n分割 基于TCP协议
connect = 'GET /wupeiqi HTTP/1.1\r\nHost: %s\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36\r\n\r\n' %url
# 发送字节 字符串转字节
sk.sendall(connect.encode('utf-8'))

# 等待服务端返回内容是阻塞的

data = sk.recv(8096)
print(data)
sk.close()

url_list = [
'www.baidu.com',
'www.cnblogs.com',
'www.jiandan.com',
]

for url in url_list:
# 串行
import socket

IO多路复用:监听多个socket是否发生变化

- 问题:
- 非阻塞
- 不等待 (报错,捕捉异常)
- sk = socket.socket()
# 写上这个就不会阻塞
sk.setblocking(False)

- 监听socket变化

什么是异步非阻塞:
- 非阻塞
- 不等待 (报错,捕捉异常)
- sk = socket.socket()
# 写上这个就不会阻塞
sk.setblocking(False)
- 异步:
- 回调,当达到某个指定的状态之后,自动调用特定函数

- 示例:nb_async.py 实现异步非阻塞模块

*** 内容梳理:
a.提高并发方案:
- 多进程,多线程,利用'异步非阻塞'模块实现单线程并发请求

b.异步非阻塞
- 异步:回调,把一个函数交给某个功能,完成后自动再执行一下这个函数
- 非阻塞:体现的就是不等待,当遇到IO请求的时候,直接获取,不等待是否已经完成,相当于执行过去,如果有报错,直接捕捉异常 sk.setblocking(False)

c.如何自定义异步非阻塞模块?
- 基于socket设置setblocking和IO多路复用来实现
- 爬虫发送Http请求本质,创建socket对象;
- IO多路复用"循环"监听socket是否发生变化,一旦发生变化,我们可以自定义操作(触发某个函数的执行)

什么是协程?
协程是"微线程",让一个线程先执行某几行代码,再跳到某处 再执行某几行代码。

通过yield实现一个协程:

def func1():
print(’adsfadsf‘)
print(’adsfadsf‘)
print(’adsfadsf‘)
yield 1
print(’adsfadsf‘)
print(’adsfadsf‘)
print(’adsfadsf‘)
yield 2
yield 3
yield 4

def func2():
print(’adsfadsf‘)
print(’adsfadsf‘)
print(’adsfadsf‘)
yield 11
yield 12
yield 19

g1 = func1()
g2 = func2()

g1.send(None)
g1.send(None)

g2.send(None)

通过greenlet模块: http://www.cnblogs.com/wupeiqi/articles/5040827.html

from greenlet import greenlet

def test1():
print 12
gr2.switch()
print 34
gr2.switch()

def test2():
print 56
gr1.switch()
print 78

gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1.switch()

如果协程+遇到IO就切换 = 》

原理:
1、什么是协程?
-协程是“微线程”,他本身是不存在的,是程序员认为创造出来并控制程序先执行某段代码 再跳到某处执行某段代码,
如果遇到非IO请求来回切换,性能就更低
如果遇到IO请求就切换的情况,性能会提高,实现并发(本质上利用IO等待的过程,再去干其他事情)

2.Http请求的本质?

3.IO多路复用的作用?
- select 内存循环检测socket是否发生变化,监听最多的socket个数1024
- poll 内存循环检测socket是否发生变化,没有限制
- epoll 回调的方式,没有个数的限制

4、异步非阻塞?
- 异步:回调
- 非阻塞:不等待

5、自定义异步非阻塞模块
- 基于事件循环
- 基于协程
- 本质:socket + IO多路复用

使用:
情况一、
import asyncio
import requests

@asyncio.coroutine
def fetch_async(func, *args):
loop = asyncio.get_event_loop()
future = loop.run_in_executor(None, func, *args)
response = yield from future
print(response.url, len(response.content))

tasks = [
fetch_async(requests.get, 'http://www.cnblogs.com/wupeiqi/'),
fetch_async(requests.get, 'http://dig.chouti.com/pic/show?nid=4073644713430508&lid=10273091')
]

loop = asyncio.get_event_loop()
results = loop.run_until_complete(asyncio.gather(*tasks))
loop.close()

情况二、
import gevent
from gevent import monkey
monkey.patch_all()
import requests

def fetch_async(method, url, req_kwargs):
print(method, url, req_kwargs)
response = requests.request(method=method, url=url, **req_kwargs)
print(response.url, len(response.content))

# ##### 发送请求 #####
gevent.joinall([
gevent.spawn(fetch_async, method='get', url='https://www.cnblogs.com/', req_kwargs={}),
gevent.spawn(fetch_async, method='get', url='https://www.baidu.com/', req_kwargs={}),
gevent.spawn(fetch_async, method='get', url='https://www.sogo.com/', req_kwargs={}),
])

情况三、
from twisted.web.client import getPage, defer
from twisted.internet import reactor

def all_done(arg):
reactor.stop()

def callback(contents):
print(contents)

deferred_list = []

url_list = ['http://www.bing.com', 'http://www.baidu.com', ]
for url in url_list:
deferred = getPage(bytes(url, encoding='utf8'))
deferred.addCallback(callback)
deferred_list.append(deferred)

dlist = defer.DeferredList(deferred_list)
dlist.addBoth(all_done)

reactor.run()

安装scarpy
scarypy模块是什么?
- 帮我们提供一个可扩展功能齐全的爬虫框架。

安装:
linux/mac pip3 install scarpy

windows:现在也直接 pip3 install scrapy

a pip3 install wheel
b 下载twsited https://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted
c 进入下载目录:执行 pip3 install Twisted-xxxxx.whl

安装:scrapy
d pip3 install scrapy -i http://pypi.douban.com/simple --trusted-host pypi.douban.com # -i 指定douban的pip源
安装 pywin32
e pip3 install pywin32 -i http://pypi.douban.com/simple --trusted-host pypi.douban.com

安装scarpy 出现 error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": http://landinghub.visualstudio.com/visual-cpp-build
解决;Microsoft .NET Framework 要升值到4.5.1以上 再安装 visualcppbuildtools full(MS Visual C++ 14报错解决) Microsoft .NET Framework 要升值到4.5.1以上

# 如果出现警告则更新组件
D:\django\PySpider\Scrapy框架\touch>scrapy genspider chouti chouti.com
:0: UserWarning: You do not have a working installation of the service_identity module: 'cannot import name 'opentype''. Please install it from
<http
s://pypi.python.org/pypi/service_identity> and make sure all of its dependencies are satisfied. Without the service_identity module, Twisted can perf
orm only rudimentary TLS client hostname verification. Many valid certificate/hostname mappings may be rejected.

https://blog.csdn.net/weixin_41917563/article/details/79978819
http://www.mamicode.com/info-detail-2162790.html

pip3 install service_identity-17.0.0-py2.py3-none-any.whl

pip3 install service_identity --force --upgrade

pip3 install pywin32 -i http://pypi.douban.com/simple --trusted-host pypi.douban.com

快速使用:
Django:
django-admin startproject mysite
cd mysite
python manage.py startapp app01
# 写代码
python manage.py runserver

Scrapy:
安装在Python的安装目录下 C:\Python36\Scripts\scrapy.exe # django-admin也在

cmd —> C:\Users\cc>D: D:\>cd django\PySpider\Scrapy框架 dir查看

- 创建项目:
D:\django\PySpider\Scrapy框架>scrapy startproject touch

项目目录:
D:\django\PySpider\Scrapy框架\touch

创建chouti的爬虫 和 博客园 chouti.py就和django的app是一样的,每一个文件就是一个爬虫
D:\django\PySpider\Scrapy框架\touch>scrapy genspider chouti chouti.com

D:\django\PySpider\Scrapy框架\touch>scrapy genspider cnblogs cnblogs.com

#Created spider 'cnblogs' using template 'basic' in module:
#touch.spiders.cnblogs

创建命令总结:
- 创建项目
scrapy startproject touch #(touch是项目名)
- 进入目录 今后创建的目录不应该有中文
cd D:\django\PySpider\MyScrapy\touch\touch
- 创建爬虫 爬取网站名命名
scrapy genspider chouti chouti.com

# -*- coding: utf-8 -*-
import scrapy
# import sys,os
# windows打印编码错误解决
# sys.stdout=io.TextIOWrapper(sys.stdout.buffer,encoding='gb18030')

class ChoutiSpider(scrapy.Spider):
name = 'chouti'
allowed_domains = ['chouti.com'] # 允许的域名找,定向只爬这一个网站
start_urls = ['http://chouti.com/'] # 入口

def parse(self, response): # 回调函数 他会去下载起始的URL 然后调用parse函数 response就是这个页面的结果的对象
pass

scrapy crawl chouti --nolog # 内部使用: twsited 具有异步+非阻塞 一个线程爬取很多页面
<200 https://dig.chouti.com/>

*** Scrapy知识总结:
1、spider 编写爬虫程序,去解析并处理请求。
def parser():
- HtmlXPathSelector
- yield item 会把item交给 pipelines ,pipelines需要在settigs里注册
- yield Request 交给调度器再执行

2、item/pipelines
配置:
ITEM_PIPELINES = {
'touch.pipelines.TouchPipeline': 300,
}

使用:应该有5个方法
class TouchPipeline(object):
def process_item(self, item, spider):
# print(item['href'])
self.f.write(item['href']+'\n')
self.f.flush() # 强制刷新到硬盘
return item

def open_spider(self, spider):
"""
爬虫开始执行时,调用
:param spider:
:return:
"""
# print('要开始了')
self.f = open('url.log','w') # 也可以追加模式

def close_spider(self, spider):
"""
爬虫关闭时,被调用
:param spider:
:return:
"""
# print('完蛋了 ')
self.f.close()

转载于:https://www.cnblogs.com/touchlixiang/p/9302452.html

路飞学城—Python—爬虫实战密训班 第三章相关推荐

  1. 路飞学城—Python爬虫实战密训班 第三章

    路飞学城-Python爬虫实战密训班 第三章 一.scrapy-redis插件实现简单分布式爬虫 scrapy-redis插件用于将scrapy和redis结合实现简单分布式爬虫:- 定义调度器- 定 ...

  2. 路飞学城—Python—爬虫实战密训班 第二章

    请求库之requests模块总结 request: # 必须背会 method url params data json headers cookies :param proxies: 如果被封IP ...

  3. 路飞学城-Python爬虫实战密训-第1章

    正式的开始学习爬虫知识,Python是一门接触就会爱上的语言.路飞的课真的很棒,课程讲解不是告诉你结论,而是在告诉你思考的方法和过程. 第一章,学习了如何爬取汽车之家以及抽屉登录并点赞. 1 impo ...

  4. 路飞学城-Python 爬虫实战密训-第 1 章

    本节学习体会: 鸡汤心得: 1.时代发展太快,要不断学习新东西,武装自己,才能跟得上时代的潮流,不然就是面临被pass的命运 2.要看清楚趋势,不要闭门造车 3.学习编程语言就跟学英语一样,方法很重要 ...

  5. 路飞学城python电子书_路飞学城-Python爬虫实战密训-第1章

    7 8 The Dormouse's story总共9 f 10 11 12

  6. 路飞学成-Python爬虫实战密训-第3章

    1,本节学习体会.心得 : 本章的内容非常多,scrapy框架的使用.对于学过django的人来说.可能要更好理解一些把.个人感觉还是挺简单的.所有的知识点一听就懂,唯一不好的就是时间太紧迫了,不的不 ...

  7. 路飞学院-Python爬虫实战密训班-第2章

    通过架设flask或django web服务器,同时后台采用requests和bs4模块来爬取web微信程序相关信息. 在代码过程中遇到一些问题,1.需要认真分析网络请求包. 2.cookies 在获 ...

  8. 路飞学院python官网-路飞学院-Python爬虫实战密训班-第1章

    学习笔记: 通过本章的学习,学习到了requests和BeautifulSoup模块的安装及使用方法.以及爬取给类网站的方法和知识点. 1.requests和BeautifulSoup 安装 pip ...

  9. 路飞学院 python_路飞学院-Python爬虫实战密训班-第1章

    学习笔记: import requests from bs4 import BeautifulSoup GET请求 r = requests.get('http://') r.text 返回heade ...

  10. 路飞学城python全栈开发_[Python] 老男孩路飞学城Python全栈开发重点班 骑士计划最新100G...

    简介 老男孩&路飞学城Python全栈开发重点班课程,作为Python全栈教学系列的重头戏,投入了全新的课程研发和教学精力,也是Python骑士计划的核心教学,由ALEX老师开班镇守,一线技术 ...

最新文章

  1. 在github上创建自己的第一个项目仓库实录
  2. 知识图谱推理问答:如何让机器像人类一样学会推理
  3. php中单引号和双引号的区别,哪个速度更快?为什么?
  4. hive 小文件数据合并
  5. HTML子选择器怎么加图,CSS伪类选择器:before、:after使用:插入字符、插入图片、插入项目编号...
  6. 堆栈图解CSAPP Bomb Lab实验解析
  7. java 文件上传 servlet_java文件上传-原始的Servlet方式
  8. 正则表达式之语法规则
  9. 对于三极管饱和状态的理解
  10. c语言选择题题及答案,C语言选择题练习及答案.doc
  11. [OPS][GPU]GPU峰值计算能力计算
  12. apex 查询_APEX初步 [6] —— SOSL查询
  13. 五句话介绍计算机英语,日常必备的英语口语句子3篇
  14. labview在不同VI间传递波形(全局变量)
  15. 回炉重造七---磁盘存储和文件系统
  16. 微软亚洲研究院院长:“中国不妨引进科技外援”
  17. 【数据分析师_02_SQL+MySQL】022_MySQL的全文检索(MyISAM,MATCH AGAINST)
  18. 如何推算图纸上点坐标
  19. simulator相关
  20. 腾讯案例实战!聊聊设计中「需求」的正确打开方式

热门文章

  1. 【今日所得】1.29。。。
  2. 【机器学习】一文详尽系列之EM算法
  3. [EMNLP18]用序列标注来进行成分句法分析
  4. 机器学习—K-means聚类、密度聚类、层次聚类理论与实战
  5. 机器学习8-集成学习
  6. 动态规划--代码随想录
  7. 关于XGB.booster()报错TypeError: 'str' object is not callable的解决方法
  8. 回顾2020年那些“领域第一本”,每一本都强烈推荐!
  9. 声纹技术:让智能语音助手真正“认得”自己
  10. 星巴克——最单纯的SNS应用