iOS开发 为app配置代理
由于对某款app的租房信息的筛选条件不满意,所以爬取了它的api以便能够根据自己的需求进行筛选。根据自己的初级爬虫经验,为了防止app封禁我的ip,所以准备通过代理服务器去访问。
过程是相当纠结啊,尝试的太多,这里就只放结论了。
笔者使用的 URLSession ,初始化前配置 URLSessionConfiguration 对象的 connectionProxyDictionary 即可。
特别提醒: host 类型为 String , 而 port 类型为 Int
ps:使用http时,需要添加ATS白名单
注: 两种代理方式貌似不能同时使用。不确定是因为我测试时上一秒代理还好好的,下一秒就挂了。
一般服务器对于爬虫是不欢迎的。真正的用户操作再快都需要一定的时间,而爬虫访问时间很短,因此相当规模的爬虫对服务器造成的负担就更大。所以服务器会对爬虫做检测,如果被抓到则可能被封掉ip或像本例一样返回其他网站。
针对检测,我们的做法就是要伪装成真正的用户。以笔者目前的理解有两点:
1 修改请求头。通过Charles抓包可以看到一次请求的头部信息,对照修改
2 设定访问延时。手速再快你也快不过自动运行的程序吧。
参考链接:
https://blogcsdnnet/c406495762/article/details/60137956
ps: 一个不错的爬虫学习系列
过程中遇到最多的就是1200错误码:无法与服务器建立安全连接。网上大多数意见是服务器SSL版本不够,因为iOS最低要求使用TLSv12的版本。对于更低一点的,就需要特别指定版本。( 由于我这里是代理字典https key用错了,才导致的1200。所以只能先在这mark一下 )
以下是网上给出的解决方法:
这是一个测试TLS的控制台命令:
nscurl --ats-diagnostics --verbose https://xxxxxxxxx
这里能自动测试哪种key能通过,随便找个https的网站试一下吧。
附上 connectionProxyDictionary keys 参见 Table 3-7
https://developerapplecom/library/content/documentation/Networking/Conceptual/SystemConfigFrameworks/SC_UnderstandSchema/SC_UnderstandSchemahtml
OSI 的七层协议体系结构的概念清晰,理论完整,当时它既复杂又不实用; TCP/IP 体系结构则不同,但是它现在却得到了非常广泛的应用,不过从实质上讲, TCP/IP 只是最上面的三层,因为最下面的网络接口层并没有什么具体内容;因此在学习计算机网络的时候往往采取折中的方法,即综合 OSI 和 TCP/IP 的优点,采用一种只有五层协议的体系结构;
iOS 开发中的网络通信主要是在传输层和应用层进行一些网络 IP 地址,端口以及协议的一些处理;首先是网络层的两种传输协议 UDP 和 TCP 的含义以及区别:
用户数据包协议;UDP 在传输数据之前不需要先建立连接远地主机的运输层在收到 UDP 报文后,不需要给出任何确认;
主要特点:
传输控制协议; TCP 提供面向连接的服务;在传输数据之前必须先建立连接,数据传输完成后要释放连接;建立连接需要通过三次握手,而释放连接需要四次握手;
主要特点:
第一次握手:客户端发送syn包(seq=x)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(seq=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。
这个问题的本质就是信道不可靠,但是通信双方需要中间传输的数据是可靠的,而要解决这个问题,无论你是在信息中包含什么信息,三次通信是理论上的最小值,所以三次握手不是TCP本身的要求,而是为了满足在不可靠信道上可靠的传输信息这一需求所致的;这里的本质需求就是,信道不可靠,数据传输要可靠,三次握手之后你先继续握手还是发数据也好,跟进行可靠信息传输的需求就没关系了,因此如果信道可靠,无论什么时候发出消息,对方一定能收到,或者你不关心是否要保证对方收到你的消息,那就能像UDP那样直接发送消息就可以;
1当主机A确认发送完数据且知道B已经接受完了,想要关闭发送数据接口(当然确认信号还是可以发),就会发FIN给主机B;
2主机B收到A发送的FIN,表示收到了,就会发送ACK回复;
3但是这时B可能还在发送数据,没有想要关闭数据口的意思,所以FIN和ACK不是同时发送的,而是等到B数据发送完,才会发送FIN给主机A;
4A收到B发来的FIN,知道B的数据也发送完了,回复ACK,A等待2MSL以后,没有收到B传来的任何消息,知道B已经收到自己的ACK了,A就关闭链接,B也关闭链接;
在客户端发送最后的ACK回复,但是该ACK可能丢失。服务端如果没有收到ACK,将不断重复发送FIN片段。所以客户端不能立即关闭,它必须确认服务端接收到了该ACK,客户端会在发送出ACK之后进入到TIME_WAIT状态,客户端会设置一个计时器,等待2MSL的时间,如果在该时间内再次收到FIN,那么客户端会重发ACK并再次等待2MSL;所谓2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果知道2MSL,客户端都没有再次收到FIN,那么客户端推断ACK已经成功接收,则结束TCP连接;
HTTP是一种无状态的连接,客户端每次读取web网页时,服务器都会认为这是一次新的会话。但有时候我们需要持久保存一些用户信息,比如登录时的用户名和密码等;而这些信息都是需要Cookie和Session来保存;
这两个的本质区别就是Cookie是保存在客户端的,而Session是保存在服务器上的;
当服务器接收到 cookie 后,会根据 cookie 中的 SessionID 来找到这个客户的 session。如果没有,则会生成一个新的 SessionID 发送给客户端。
HTTP 连接使用的是"请求--响应"的方式,不仅在请求时需要先建立连接,而且需要客户端向服务器发出请求后,服务器端才能回复数据;一次请求后立即断开;HTTP 使用的的面向连接的 TCP 作为传输层协议,保证了数据的可靠性;但是 HTTP属于无状态,无连接;虽然使用了 TCP 连接,但通信的双方不需要先建立连接;
socket 连接通常情况下就是 TCP 连接,因此 socket 连接一旦建立,通信双方即可开始互相发送数据内容,直到双方的连接断开;但在实际应用中,客户端和服务器之间的通行防火墙会关闭长时间处于非活跃状态的连接而导致 socket 连接中断,因此需要通过轮询告诉网络该连接处于活跃状态;
连接过程分为三个步骤:服务器监听,客户端请求,连接确认;
服务器监听 :服务器端套接字并不定位具体的客户端套接字,而是处于等待连接状态,实时监测网络状态,等待客户端的连接请求;
客户端的连接请求 :指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字,为此客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端的套接字的地址和端口号,然后就向服务器端套接字提出连接请求;
连接确认 :当服务器端套接字监听到或者说收到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,双方就正式建立连接,而服务器端的套接字继续处于监听状态,继续接受其它客户端套接字的连接请求;
HTTP的 URL 的一般形式是: http://<主机>:<端口>/<路径>
HTTP 的默认端口号是:80;
HTTP 有两类报文:
1请求报文---从客户端向服务器发送的请求报文
2响应报文---从服务器到客户的回答
特点:所有的请求参数都拼接都 URL 的后面;
缺点:
特点:
1xx 保留响应保留;
2xx 请求成功接收;
3xx 为完成请求客户端需要进一步细化请求;
4xx 客户端请求错误(参数,方式不正确);
5xx 服务器端有错误;
1、网络请求中常用的有Get请求,Post请求,还有Head、Put、Delete、Options、Trace、Connect等
GET 获取指定资源
POST 向指定资源提交数据进行处理请求,在RESTful风格中用于新增资源
HEAD 获取指定资源头部信息
PUT 替换指定资源(不支持浏览器操作)
DELETE 删除指定资源
OPTIONS 允许客户端查看服务器的性能
TRACE 回显服务器收到的请求,主要用于测试或诊断
CONNECT 预留给能够将连接改为管道方式的代理服务器(HTTP代理使用)
2、上传在网页中最常用的就是POST请求了,将编码到POST请求体(body)中,通过请求数据一起发送到服务器上;
3、在iOS开发中,上传的请求体非常难写,格式要求非常严格,出一点错误都会造成上传失败,或请求数据失败,先看格式:
--Boundary+72D4CD655314C423
Content-Disposition: form-data; name="uploadFile"; filename="001png"
Content-Type:image/png
Content-Transfer-Encoding: binary
contents of borispng
--Boundary+72D4CD655314C423--
这是一个不带其他任务参数,body中只有一张图就要写成这样
分别说明一下:
--Boundary+72D4CD655314C423 // 分割符,以“--”开头,后面的字随便写,只要不写中文即可
Content-Disposition: form-data; name="uploadFile"; filename="001png" // 这里注明服务器接收的参数(类似于接收用户名的userName)及服务器上保存的文件名
Content-Type:image/png // 类型为png
Content-Transfer-Encoding: binary // 编码方式
// 这里是空一行,必不可少!!
contents of borispng // 数据部分
--Boundary+72D4CD655314C423-- // 分隔符后面以"--"结尾,表明结束
Django+mysql解决你的需求,
2年前我也是没有一项服务端技能来支持我的app,找人配合麻烦多多。
后来一咬牙自学Django,在两周内基本掌握。
为什么这么快,因为移动app的后端一般不会产生页面,只对移动端的http请求进行校验和返回json就行了。
你作为一个移动开发者如果选Django的话,找本书入门一下Python,大约一周就够,我是看的这本在线书woodpeckerorgcn/diveintopython/toc/indexhtml,其实学到第七章就够了,其他知识可以需要时再补。
然后第二周入门Django,一Python的web快速开发框架,有框架作者写的在线书
djangobookpy3kcn/20/
,这书的实践性非常强跟着做不需要指导也可以入门。学到十章就够开发移动app后端了,由于Django自带一个数据库管理页面,所以已经满足你的要求了。
最爽的是,GAE,和SAE都支持Django,可以方便的把你的服务架设到云端,用于初期测试。在数据流量小的时候,基本不花钱,非常方便。
做安卓开发软件环境:Eclipse+ADT 硬件环境:电脑 服务器:单机的app不需要,需要的网上租 服务器的软件环境和电脑网站一样:服务器tomcat,JBoss,WebSphere,WebLogic,Resin。数据库:MySQL,Oracle,SqlServer 手机端:SQLite
0条评论