爬虫之网络请求中的那些事

urllib库

urllib库是python自带的内置库,不需要安装

urllib库是Python中一个最基本的网络请求库。可以模拟浏览器的行为,向指定的服务器发送一个请求,并可以保存服务器返回的数据

在Python3的urllib库中,所有和网络请求相关的方法,都被集到urllib.request模块中

request中常用的方法

urlopen函数

urlopen函数用来创建一个表示远程url的类文件对象,然后像本地文件一样操作这个类文件对象来获取远程数据

部分源码

def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
*, cafile=None, capath=None, cadefault=False, context=None):
'''Open the URL url, which can be either a string or a Request object. *data* must be an object specifying additional data to be sent to
the server, or None if no such data is needed. See Request for
details.
'''

参数详解

  • url:请求的url
  • data:请求的data,如果设置了这个值,将变成post请求
  • 返回值:返回值是一个http.client.HTTPResponse对象,这个对象是一个类文件句柄对象。有read(size)、readline、readlines以及getcode等方法

句柄如何理解

数值上,是一个32位无符号整型值(32位系统下);逻辑上,相当于指针的指针;形象理解上,是Windows中各个对象的一个唯一的、固定不变的ID;作用上,Windows使用句柄来标识诸如窗口、位图、画笔等对象,并通过句柄找到这些对象

from urllib import request

'''
Open the URL url, which can be either a string or a Request object
'''
resp = request.urlopen('https://www.sogou.com/')
print(resp) # 返回一个HTTPresponse对象,<http.client.HTTPResponse object at 0x000002E0CADA0C50>
print(resp.read()) # 返回网页源代码
print(resp.read(1024)) # 返回1024字节大小的数据
print(resp.readline()) # 返回一行数据
print(resp.readlines()) # 返回多行数据
print(resp.getcode()) # 返回状态码:200

urlretrieve函数

这个函数可以方便的将网页上的一个文件保存到本地。以下代码可以非常方便的将搜狗的首页下载到本地:

from urllib import request
request.urlretrieve('https://www.sogou.com/','sogou.html')

部分源码

def urlretrieve(url, filename=None, reporthook=None, data=None):
"""
Retrieve a URL into a temporary location on disk. Requires a URL argument. If a filename is passed, it is used as
the temporary file location. The reporthook argument should be
a callable that accepts a block number, a read size, and the
total file size of the URL target. The data argument should be
valid URL encoded data. If a filename is passed and the URL points to a local resource,
the result is a copy from local file to new file. Returns a tuple containing the path to the newly created
data file as well as the resulting HTTPMessage object.
"""



格式

request.urlretrieve(url,文件名)

示例

from urllib import request

request.urlretrieve('https://th.bing.com/th/id/OIP.NX9KpjV4Mk_e72YV_6nPNgDhEs?w=182&h=243&c=7&r=0&o=5&dpr=1.25&pid=1.7','haizei.jpg')

urlencode、parse_qs函数

urlencode可以把字典数据转换为URL编码的数据,如果我们使用浏览器发送一个请求的时候,url中携带汉字,那么浏览器就会自动进行了url编码

如何解码?使用parse_qs函数就可以解码了

部分源码

def urlencode(query, doseq=False, safe='', encoding=None, errors=None,
quote_via=quote_plus):
'''Encode a dict or sequence of two-element tuples into a URL query string.'''
def parse_qs(qs, keep_blank_values=False, strict_parsing=False,
encoding='utf-8', errors='replace', max_num_fields=None):
'''Parse a query given as a string argument.'''

示例1

from urllib import parse

data = {'name': 'Hammer', 'age': 18}
# 编码
res = parse.urlencode(data)
print(res) # name=Hammer&age=18 # 解码
ret = parse.parse_qs(res)
print(ret) # {'name': ['Hammer'], 'age': ['18']}

示例2

浏览器会帮助我们进行url编码,那么我们使用pycharm进行爬取数据的时候,中文需要我们自己处理

from urllib import parse,request
data1 = {'q':'古力娜扎'}
res1 = parse.urlencode(data1)
print(res1,type(res1)) # q=%E5%8F%A4%E5%8A%9B%E5%A8%9C%E6%89%8E <class 'str'> res = request.urlopen('https://www.bing.com/search?'+res1)
print(res.read())

示例3

这里需要注意的是,url字符串编码和encode方法编码的结果是不一样的

data = {'Name':'古力娜扎'}
res2 = parse.urlencode(data)
print(res2) # Name=%E5%8F%A4%E5%8A%9B%E5%A8%9C%E6%89%8E
qs = parse.quote('古力娜扎')
print(qs) # %E5%8F%A4%E5%8A%9B%E5%A8%9C%E6%89%8E print('古力娜扎'.encode('utf8')) # b'\xe5\x8f\xa4\xe5\x8a\x9b\xe5\xa8\x9c\xe6\x89\x8e'

urlparse、urlsplit函数:

有时候拿到一个url,想要对这个url的各个组成部分进行分割,那么这个时候使用urlparse或者urlsplit来进行分割;

URL组成:

  • 协议部分:http/https
  • 域名部分:www.baidu.com / ip地址
  • 端口部分:跟在域名后面,以:作为分隔符,不写的时候使用端口,比如127.0.0.1:8000
  • 虚拟目录部分:从域名后的第一个“/”开始到最后一个“/”为止,是虚拟目录部分。虚拟目录也不是一个URL必须的部分。比如:127.0.0.1:8000/backend/3.html,backend就是虚拟目录
  • 文件名部分:从域名后的最后一个“/”开始到“?”为止,是文件名部分,如果没有“?”,则是从域名后的最后一个“/”开始到“#”为止,是文件部分,如果没有“?”“#”,那么从域名后的最后一个“/”开始到结束,都是文件名部分。文件名部分也不是一个URL必须的部分,如果省略该部分,则使用默认的文件名
  • 锚部分:从“#”开始到最后,都是锚部分
  • 参数部分:从?开始到#为止之间的部分为有参部分,又称为搜索部分或者查询部分,参数允许有多个,一般用&做分隔符

部分源码

# urlsplit函数
def urlsplit(url, scheme='', allow_fragments=True):
'''
Parse a URL into 5 components:
<scheme>://<netloc>/<path>?<query>#<fragment>
Return a 5-tuple: (scheme, netloc, path, query, fragment).
'''
# urlparse函数
def urlparse(url, scheme='', allow_fragments=True):
"""Parse a URL into 6 components:
<scheme>://<netloc>/<path>;<params>?<query>#<fragment>
Return a 6-tuple: (scheme, netloc, path, params, query, fragment).
Note that we don't break the components up in smaller bits
(e.g. netloc is a single string) and we don't expand % escapes."""

注意

通过源码注释的对比,我们发现urlparse返回的参数比urlsplit返回的参数多一个params,params是url中的可选参数

示例

from urllib import parse
res = parse.urlparse('https://zzk.cnblogs.com/my/s/blogpost-p?Keywords=python')
ret = parse.urlsplit('https://zzk.cnblogs.com/my/s/blogpost-p?Keywords=python')
print(res,type(res))
print(ret,type(ret))
'''
结果:
ParseResult(scheme='https', netloc='zzk.cnblogs.com', path='/my/s/blogpost-p', params='', query='Keywords=python', fragment='') <class 'urllib.parse.ParseResult'>
SplitResult(scheme='https', netloc='zzk.cnblogs.com', path='/my/s/blogpost-p', query='Keywords=python', fragment='') <class 'urllib.parse.SplitResult'>
'''
# 返回的是一个对象,那么可以通过点的方法获取到该对象的属性值
print(res.scheme,res.params)

request.Request类

Request类也是用于处理网络请求,如果想要在请求的时候增加一些请求头,那么就必须使用request.Request类来实现,比如要增加一个User-Agent

部分源码:

class Request:
def __init__(self, url, data=None, headers={},
origin_req_host=None, unverifiable=False,
method=None):

通过源码我们可以看到,必传的参数有url和headers(传字典)

from urllib import request
header = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36 Edg/99.0.1150.39'
}
res = request.Request('https://www.cnblogs.com/',headers=header)
print(res) # <urllib.request.Request object at 0x000001959F347CF8> ret = request.urlopen(res)
print(ret.read()) # 返回网页源代码

我们可以通过添加UA来获取更多的网页源代码··

实战:爬取猫眼票房数据

from urllib import request
import json url = 'https://piaofang.maoyan.com/dashboard-ajax?orderType=0&uuid=7cba1a83-0143-4e91-b431-6e48cf2c4f57&timeStamp=1647662149259&User-Agent=TW96aWxsYS81LjAgKFdpbmRvd3MgTlQgMTAuMDsgV2luNjQ7IHg2NCkgQXBwbGVXZWJLaXQvNTM3LjM2IChLSFRNTCwgbGlrZSBHZWNrbykgQ2hyb21lLzk5LjAuNDg0NC41MSBTYWZhcmkvNTM3LjM2IEVkZy85OS4wLjExNTAuMzk%3D&index=442&channelId=40009&sVersion=2&signKey=fb7aa416ff3c852bfe69b01ee7952272'
header = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36 Edg/99.0.1150.39'
} ret = request.Request(url,headers=header)
resp = request.urlopen(ret)
# print(resp.get('movieList').get('data').get('list').decode('utf8'))
data = resp.read().decode('utf8')
'''注意这里获取的是json格式数据'''
data = json.loads(data)
data_list = data.get('movieList').get('data').get('list')
for line in data_list:
print(line.get('movieInfo')) '''结果'''
{'movieId': 341955, 'movieName': '新蝙蝠侠', 'releaseInfo': '上映2天'}
{'movieId': 338380, 'movieName': '神秘海域', 'releaseInfo': '上映6天'}
{'movieId': 1446115, 'movieName': '长津湖之水门桥', 'releaseInfo': '上映47天'}
{'movieId': 1405863, 'movieName': '熊出没·重返地球', 'releaseInfo': '上映47天'}
{'movieId': 1433696, 'movieName': '这个杀手不太冷静', 'releaseInfo': '上映47天'}
{'movieId': 1300821, 'movieName': '花束般的恋爱', 'releaseInfo': '上映26天'}
{'movieId': 1383307, 'movieName': '奇迹·笨小孩', 'releaseInfo': '上映47天'}
{'movieId': 1435147, 'movieName': '我们的冬奥', 'releaseInfo': '上映29天'}
{'movieId': 1309268, 'movieName': '可不可以你也刚好喜欢我', 'releaseInfo': '上映9天'}
{'movieId': 1265626, 'movieName': '印度女孩', 'releaseInfo': '上映2天'}
{'movieId': 1367251, 'movieName': '狙击手', 'releaseInfo': '上映47天'}
{'movieId': 1445469, 'movieName': '喜羊羊与灰太狼之筐出未来', 'releaseInfo': '上映47天'}
{'movieId': 1303796, 'movieName': '“炼”爱', 'releaseInfo': '上映2天'}
{'movieId': 1405621, 'movieName': '玛纳斯人之失落的秘境', 'releaseInfo': '上映首日'}
{'movieId': 1214749, 'movieName': '纽约的一个雨天', 'releaseInfo': '上映23天'}
{'movieId': 1302341, 'movieName': '*小道', 'releaseInfo': ''}
{'movieId': 1247341, 'movieName': '妖怪手表:永远的朋友', 'releaseInfo': '上映8天'}
{'movieId': 1396517, 'movieName': '年少有你', 'releaseInfo': '上映2天'}
{'movieId': 1338396, 'movieName': '如果有一天我将会离开你', 'releaseInfo': '上映9天'}

实战:爬取别逗了网站信息

from urllib import request,parse

for page  in range(9270,9273):
header = {
'user - agent': 'Mozilla / 5.0(Windows NT 10.0;Win64; x64) AppleWebKit /537.36KHTML, likeGecko) Chrome/99.0.4844.51 Safari / 537.36 Edg / 99.0.1150.39'
}
url = f'https://www.biedoul.com/index/{page}/'
request.Request(url=url,headers=header)
res = request.urlopen(url)
request.urlretrieve(url,f'{page}.html')
page_data = res.read().decode('utf8')
print(page_data)

ProxyHandler处理器(代理设置)

很多时候我们玩游戏开外挂,飞天遁地透视····最后被封号~我们爬虫也类似,老是不断的去请求,人家也会烦,封你的ip;

在我们爬取数据的时候如果对服务器请求的次数过多的时候,服务器也不傻会识别出来是非正常请求,一般采取我措施是封IP措施,这时候我们的IP就不能正常访问,可以通过“换小号继续玩”;

查看http请求的一些参数:http://httpbin.org

查看没有使用代理的ip地址:http://httpbin.org/ip

from urllib import request
# No Proxy
url = 'http://httpbin.org/ip'
resp = request.urlopen(url)
print(resp.read()) # b'{\n "origin": "112.64.68.252"\n}\n'

设置代理ip

通过设置代理ip解决封ip问题,原理是通过请求代理服务器,然后通过代理服务器请求目标服务器,然后返回数据

常用的代理有:

from urllib import request

# Use Proxy
url = 'http://httpbin.org/ip'
# 使用ProxyHandler,传入代理构造一个handler
handler = request.ProxyHandler({'http':'106.15.197.250:8001'})
# 使用上面的handler构造opener
opener = request.build_opener(handler)
# 使用opener发送请求
resp = opener.open(url)
print(resp.read()) # b'{\n "origin": "106.15.197.250"\n}\n'
'''我们可以看到ip并不是以前的ip了,这样就设置成功了,但是缺点就是免费的不稳定'''

Cookie

什么是cookie?

指某些网站为了辨别用户身份、进行 session 跟踪而储存在用户本地终端上的数据,cookie存储的数据量有限,不同的浏览器有不同的存储大小,但一般不超过4KB。因此使用cookie只能存储一些小量的数据;

Cookie、Session

我们知道HTTP的四大特征:

  • 基于请求响应:服务端永远不会主动给客户端发消息 必须是客户端先发请求,如果想让服务端主动给客户端发送消息可以采用其他网络协议;
  • 基于TCP/UDP、IP作用于应用层之上的协议
  • 无状态:不保存客户端的状态信息,不知道是属于哪一个用户发过来的请求,每次过来都仿佛第一次看见(待你如初恋)
  • 无连接/短连接:两者请求响应之后立刻断绝关系

  • Cookie的出现就是为了解决无状态,用来辨别身份登录一次,下一次来携带Cookie就知道是谁了;

cookie的格式

Set-Cookie: NAME=VALUE;Expires/Max-age=DATE;Path=PATH; Domain=DOMAIN_NAME;SECURE

参数意义

  • NAME:cookie的名字。
  • VALUE:cookie的值。
  • Expires:cookie的过期时间。
  • Path:cookie作用的路径。
  • Domain:cookie作用的域名。
  • SECURE:是否只在https协议下起作用。

实战:爬虫使用Cookie实现模拟登录

from urllib import request

url = 'https://www.zhihu.com/hot'
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36',
'cookie': '_zap=8812b5e0-0b83-4ce1-9ac5-c913debd77c5; d_c0="AIDel4RQJxSPTp9hk0DqVuFjlrklYMgxsHM=|1639015736"; _9755xjdesxxd_=32; YD00517437729195%3AWM_TID=cfvcktVDh9REFEQRAVJ%2B97fYipUcBdd5; Hm_lvt_98beee57fd2ef70ccdd5ca52b9740c49=1642496751,1642507682,1642515429,1642954789; _xsrf=3S5Nqf0sEQkI3Cln9pmAI6lgYnk6Wxoh; __snaker__id=IKbmra7CqY74Sn2D; YD00517437729195%3AWM_NI=utbfMp3td5HSlvkH%2FYeFIlzsYQABzUsxftqGf3FISbVKXYoqU0oCNKXIYIGU4%2Bb1V3MvuX1jFJyMVSE8dQ2rCDro8DGNd1ZNcs%2BOCpPc8OSf67cfOoqOnWaAR%2B3MfelJdkU%3D; YD00517437729195%3AWM_NIKE=9ca17ae2e6ffcda170e2e6ee9aae429789fa90e44083b08ab7c55e828b9aaaf87efba899a9ef658ca681d2fb2af0fea7c3b92ab7acae87d07cf1acacd6cb59b0aaa5a9ae53a79a878df9799b8f8fa3f95fb1a8aa95f44da6ed8aaad26a969598baee7b97f0a1a4cd419c9797aac65ff8f5aed2d5398faabbb9b4628696b7aed55987e8acb2b17a819cbe90bb508592acd2d946a1ade5b0c27c94bdf8b0d26ef6e9ad87ce65b391a2b8e44b92f5fdaee56fb096ac8cd837e2a3; gdxidpyhxdE=V9Pnc%5CLTb2HTGVfNr3WCQW%2FW%5CCPZOK0XnGxAObaD1RC8G7lwZLG5UoGtylAs8UsXb6no7b1wQyxAg%2FPw1xBoaf%2BUulfG9%2BxkiQ0JwMdYZodeVJ6V1lpw1YfGScmJnPoMVyVrarJ%5CzZja6%2FMUjsb4IjY1wB2gyVrmaOoSKxvHeJfUiKGZ%3A1647680377803; captcha_session_v2=2|1:0|10:1647679931|18:captcha_session_v2|88:RlMvRkdSRUU4dCtjMnlPRmVnN2JjQ2EzeCtJT3p1YkViREM2L3R1TlByMXdna0RRRWpiSWVwMUd6cWFxa2dKdQ==|b723dce9ca2e90df4737d71cbe58ceb6006083307013e7b44c5557d89ec4ff2f; captcha_ticket_v2=2|1:0|10:1647679942|17:captcha_ticket_v2|704:eyJ2YWxpZGF0ZSI6IkNOMzFfUHZ1dGhpeHdVa3VCcGM3S3Z4MDBwcGVDd2ZLV0dLVWtCQVRpZlFuUGNQZi15U3hZMnJQMkQxYlE0ZTlYSzlrTTdzTnVuaXZySjZyb3RYcnlwa0hUODhVbFFzU1poT0NIR0FVYU56YlJPc3lEYzlGbldQbFp2VGRVTXBMX3J4djVVbUhtd1VWRGI4MFB1QUhyVUxWUzhDVGpYN1lHaHBYRDBJQndwcVZUZDFsUWVqTXFWUHE0MnFicGhGSEFQZFVsb0dXd1FYd3g3X21VekdUd0ZUWllhNUtoam9vT1NwMHQxUUxzWEZXZmN2d0N0Y3NLamxvZ244LTRxd2t2Zk41WVZpc3dlOVJKUkwyZ21vNWFBcy03N0ZqbXFBZXNiRlpiRklIeC5ndnRkSUJlUi5CR2hQR05VQnMxWGRHUFh3aG11TGlrdEVhbnNoR1dzN2RLZXVzWks1eG1zMXVSeXdqaGR4VW1GeEVIc1VNZ2xQMXU1NnNyVmxCWUdTSmFESlJHNU9zUnlDVG1mTHE3OW92MFdiV1lYQzRmdXFXOVVaMnlHLjRKWEFNQTZVeHh6cXBGcExjLWtWd1FKMG9UbG03OFVyYmlRMmFJeVg4emhJVkd4WU5uRnRmNmo4NFdjZG54SS5WQ1F6LXhjRWNuS21hNi1CVVJTcHVULXNwMyJ9|deb333726cc56b3900502d1c8ecd3dd1d91e56ba4090ee683a0af86c18986274; z_c0=2|1:0|10:1647679962|4:z_c0|92:Mi4xaGlpOEJBQUFBQUFBZ042WGhGQW5GQ1lBQUFCZ0FsVk4ydWNpWXdCUVpFSXBYM2JBWTdMSnFEUHZ6VnhIT01HZXd3|63b889aa3a6ee8c58b1e84d9a7de39bfa84a8b8c74f14775399c623f0d73f11a; q_c1=87cdf895ba3444b8bdf4fc2bf51766c2|1647679962000|1647679962000; NOT_UNREGISTER_WAITING=1; tst=h; '
}
hdr = request.Request(url, headers=headers)
resp = request.urlopen(hdr)
print(resp.read().decode('utf8'))

http.cookiejar模块

介于每次处理cookie比较麻烦还得从浏览器上copy过来使用,现在使用cookiejar模块来进行优化;

该模块主要的类有CookieJar、FileCookieJar、MozillaCookieJar、LWPCookieJar。这四个类的作用分别如下:

  • CookieJar:管理HTTP cookie值、存储HTTP请求生成的cookie、向传出的HTTP请求添加cookie的对象。整个cookie都存储在内存中,对CookieJar实例进行垃圾回收后cookie也将丢失;
  • FileCookieJar (filename,delayload=None,policy=None):从CookieJar派生而来,用来创建FileCookieJar实例,检索cookie信息并将cookie存储到文件中。filename是存储cookie的文件名。delayload为True时支持延迟访问访问文件,即只有在需要时才读取文件或在文件中存储数据;
  • MozillaCookieJar (filename,delayload=None,policy=None):从FileCookieJar派生而来,创建与Mozilla浏览器 cookies.txt兼容的FileCookieJar实例;
  • LWPCookieJar (filename,delayload=None,policy=None):从FileCookieJar派生而来,创建与libwww-perl标准的 Set-Cookie3 文件格式兼容的FileCookieJar实例;
from urllib import request
from urllib import parse
from http.cookiejar import CookieJar # 登录:https://i.meishi.cc/login.php?redirect=https%3A%2F%2Fwww.meishij.net%2F
#个人网页https://i.meishi.cc/cook.php?id=13686422 headers={
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'
} #1.登录
#1.1 创建cookiejar对象
cookiejar = CookieJar()
#1.2 使用cookiejar创建一个HTTPCookieProcess对象
handler = request.HTTPCookieProcessor(cookiejar)
#1.3 使用上一步的创建的handler创建一个opener
opener = request.build_opener(handler)
#1.4 使用opener发送登录请求 (账号和密码) post_url = 'https://i.meishi.cc/login.php?redirect=https%3A%2F%2Fwww.meishij.net%2F'
post_data = parse.urlencode({
'username':'1097566154@qq.com',
'password':'wq15290884759.'
})
'''如果登录后发送的是GET请求,那么就不需要携带登录信息直接获取'''
req = request.Request(post_url,data=post_data.encode('utf-8'))
opener.open(req) #2.访问个人网页
url = 'https://i.meishi.cc/cook.php?id=13686422'
rq = request.Request(url,headers=headers)
resp = opener.open(rq)
print(resp.read().decode('utf-8'))

Cookie加载与保存

from urllib import request
from http.cookiejar import MozillaCookieJar # 保存
cookiejar = MozillaCookieJar('cookie.txt')
handler = request.HTTPCookieProcessor(cookiejar)
opener = request.build_opener(handler)
resp = opener.open('https://www.baidu.com')
# resp = opener.open('http://www.httpbin.org/cookies/set/course/abc') cookiejar.save(ignore_discard=True,ignore_expires=True)
# ignore_discard=True  即使cookies即将被丢弃也要保存下来
# ignore_expires=True 如果cookies已经过期也将它保存并且文件已存在时将覆盖
from urllib import request
from http.cookiejar import MozillaCookieJar #加载
cookiejar = MozillaCookieJar('cookie.txt')
cookiejar.load() for cookie in cookiejar:
print(cookie)

爬虫中网络请求的那些事之urllib库的更多相关文章

  1. Java生鲜电商平台-SpringCloud微服务架构中网络请求性能优化与源码解析

    Java生鲜电商平台-SpringCloud微服务架构中网络请求性能优化与源码解析 说明:Java生鲜电商平台中,由于服务进行了拆分,很多的业务服务导致了请求的网络延迟与性能消耗,对应的这些问题,我们 ...

  2. volley中网络请求

    首先使用Volley类创建 RequestQueue queue = Volley.newRequestQueue(this);  Making GET Requests final String u ...

  3. ios中网络请求缓存

    #import <Foundation/Foundation.h> #import "ASIFormDataRequest.h" @protocol NetWorkde ...

  4. Android中的异步网络请求

    本篇文章我们来一起写一个最基本的Android异步网络请求框架,借此来了解下Android中网络请求的相关姿势.由于个人水平有限,文中难免存在疏忽和谬误,希望大家可以指出,谢谢大家:) 1. 同步网络 ...

  5. iOS开发网络请求——大文件的多线程断点下载

    iOS开发中网络请求技术已经是移动app必备技术,而网络中文件传输就是其中重点了.网络文件传输对移动客户端而言主要分为文件的上传和下载.作为开发者从技术角度会将文件分为小文件和大文件.小文件因为文件大 ...

  6. 网络请求工具--AFNetworking 分类: ios技术 2015-02-03 08:17 76人阅读 评论(0) 收藏

    在我们开发过程中,网络请求是必不可少的,对于网络框架,现在主流的大概只有三类:ASI框架: HTTP终结者(已经停止更新了),MKNetworkKit ,AFN.今天我就来浅谈一下这个AFN AFNe ...

  7. Android网络请求框架AsyncHttpClient实例详解(配合JSON解析调用接口)

    最近做项目要求使用到网络,想来想去选择了AsyncHttpClient框架开进行APP开发.在这里把我工作期间遇到的问题以及对AsyncHttpClient的使用经验做出相应总结,希望能对您的学习有所 ...

  8. App 组件化/模块化之路——如何封装网络请求框架

    App 组件化/模块化之路——如何封装网络请求框架 在 App 开发中网络请求是每个开发者必备的开发库,也出现了许多优秀开源的网络请求库.例如 okhttp retrofit android-asyn ...

  9. xamarin android网络请求总结

    xamarin android中网络请求的框架非常多,在项目中使用的是第三方的一个网络请求框架restsharp,应该是github上.net网络请求最多star的框架,没有之一.这里就简单汇总了其他 ...

随机推荐

  1. DHCP原理与LINUX下的配置

    DHCP原理与LINUX下的配置 目录 DHCP原理与LINUX下的配置 一.DHCP工作原理 1.DHCP概述 2.DHCP的优势 3.DHCP的分配方式 (1)自动分配 (2)手动分配 (3)动态 ...

  2. PyTorch深度学习入门笔记(一)PyTorch环境配置及安装

    @ 目录 一.工具安装 1.1 Anaconda 安装 1.2 Pytorch安装 二.编辑器安装 2.1 Pycharm安装 2.2 Jupyter安装 OS: ubuntu 20.04(虚拟机) ...

  3. 「 题解 」P2487 [SDOI2011]拦截导弹

    简单题意 给定 \(n\) 个数对 \((h_i, v_i)\). 求: 最长不上升子序列的长度. 对于每个 \(i\),分别求出包含数对 \((h_i, v_i)\) 的最长上升子序列的个数和最长不 ...

  4. ROS::message_filters中的一个报错(mt::TimeStamp……)

    『方便检索』 ros::Time msg_time = mt::TimeStamp<typename mpl::at_c<Messages, i>::type>::value( ...

  5. 帆软报表(finereport)雷达图钻取详细点新页面展示

    添加参数栏,季度下拉框的空间名为combobox0 添加雷达图,通过第三页面做跳转 雷达图钻取.cpt为联动钻取的第三页面 添加纬度(所点击钻取的点) 参数   wd 添加季度参数 jd    值为季 ...

  6. VLAN介绍及实验

    目录 一.VLAN 1.1.VLAN的概念及优势 1.2.VLAN的种类 1.3.静态VLAN的配置 1.4.Trunk的作用 1.5.配置实验 1.搭建拓扑图 2.交换机SW1配置情况 3.交换机S ...

  7. 03.python语法入门--注释、变量

    注释 """多行注释加在整个py文件的开头用来对该py文件进行一个整体性的说明通常一个py中只有一个多行注释"""​# 这是一行贼溜的代码p ...

  8. 编译安装 tree 命令

    文章目录 下载源码包 编译源码包 tree下载地址:http://mama.indstate.edu/users/ice/tree/ Centos发行版,可以直接使用命令 yum -y install ...

  9. 五、模板方法设计模式及在Spring中的应用

    模板方法模式是一种行为型设计模式,具体定义网络上很多资源搜到本文不赘述. 如果字面理解比较抽象的话,那以生活中简单的行为为例:天热了,到了晚上妈妈都要将今天没有吃完的饭菜放入冰箱.将饭菜放入冰箱就是一 ...

  10. 故障分析:网络闪断引发的ServiceStack.Redis死锁问题

    背景说明 某天生产环境发生进程的活跃线程数过高的预警问题,且一天两个节点分别出现相同预警.此程序近一年没出现过此类预警,事出必有因,本文就记录下此次根因分析的过程. 监控看到的线程数变化情况: 初步的 ...