由于对某款app的租房信息的筛选条件不满意,所以爬取了它的api以便能够根据自己的需求进行筛选。根据自己的初级爬虫经验,为了防止app封禁我的ip,所以准备通过代理服务器去访问。
过程是相当纠结啊,尝试的太多,这里就只放结论了。
提前了解:
- http方式的代理只能访问http网站。
- https方式的代理只能访问https网站。
注:上面的“只能”指的是访问失败或者能访问但隐藏不了ip。
ps:有时代理稳定性也很重要,不行就换换吧。
验证方式:
- http代理:http://www.whatismyip.com.tw
- https代理:https://ip.cn
直接浏览器访问就能看到你本机公网ip。设置代理后再访问,如果能看到你设置的代理ip,则表示成功。
另外给两个免费代理获取网站:
http://www.xicidaili.com/ : 不要访问太频繁,笔者已经被block了 !_!
https://proxy.mimvp.com/: 免费的在页面最下方
上代码(Swift):
笔者使用的URLSession
,初始化前配置URLSessionConfiguration
对象的connectionProxyDictionary
即可。
class HTTPProxyPool: NSObject, URLSessionDelegate {
/// 设置HTTP代理
///
/// - Returns: 使用了代理的session
func tempForSetProxy() -> URLSession? {
let host = "218.72.108.124"
let port = 18118
let proxyDict: [String: Any] = [
// 激活http代理
String(kCFNetworkProxiesHTTPEnable) : true,
// 端口号,注意是 Int 类型
String(kCFNetworkProxiesHTTPPort) : port,
// 代理ip,注意是 String 类型
String(kCFNetworkProxiesHTTPProxy) : host
]
// 使用默认config
let config = URLSessionConfiguration.default
// 设置代理字典
config.connectionProxyDictionary = proxyDict
let session = URLSession(configuration: config)
// 配置请求
let url = URL(string: "http://www.whatismyip.com.tw")
var req = URLRequest(url: url!)
// 创建并执行网络请求任务
let task = session.dataTask(with: req) { (data, res, err) in
if let data = data {
// 如果你的返回值是谋道的广告(至少我是),请往后看。
// 此时你需要换ip ······
print(String(data: data, encoding: .utf8))
}
}
task.resume()
return session
}
}
特别提醒:host
类型为String
, 而port
类型为Int
.
- 上面的代码展示的是http代理的设置。针对http代理,proxyDict也可替换成下面这个:
{
// 激活http代理
"HTTPEnable" : true,
// 代理ip
"HTTPProxy" : host,
// 端口号
"HTTPPort" : port
}
ps:使用http时,需要添加ATS白名单
- 使用https代理
1. 首先确定你使用的代理是https方式的
2. 访问的url也是https。这里就是将url换成https://ip.cn
3. 替换proxyDict
为以下内容:
{
// 激活https代理
"HTTPSEnable" : true,
// 代理ip
"HTTPSProxy" : host,
// 端口号
"HTTPSPort" : port
}
注:两种代理方式貌似不能同时使用。不确定是因为我测试时上一秒代理还好好的,下一秒就挂了。
题外话1:关于返回值是其他html
一般服务器对于爬虫是不欢迎的。真正的用户操作再快都需要一定的时间,而爬虫访问时间很短,因此相当规模的爬虫对服务器造成的负担就更大。所以服务器会对爬虫做检测,如果被抓到则可能被封掉ip或像本例一样返回其他网站。
针对检测,我们的做法就是要伪装成真正的用户。以笔者目前的理解有两点:
1. 修改请求头。通过Charles抓包可以看到一次请求的头部信息,对照修改
2. 设定访问延时。手速再快你也快不过自动运行的程序吧。
参考链接:
https://blog.csdn.net/c406495762/article/details/60137956
ps: 一个不错的爬虫学习系列
题外话2:记录一个看起来挺重要的问题(未能验证)
过程中遇到最多的就是1200错误码:无法与服务器建立安全连接。网上大多数意见是服务器SSL版本不够,因为iOS最低要求使用TLSv1.2的版本。对于更低一点的,就需要特别指定版本。( 由于我这里是代理字典https key用错了,才导致的1200。所以只能先在这mark一下 )
以下是网上给出的解决方法:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>your.https.server</key>
<dict>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSExceptionMinimumTLSVersion</key>
<string>TLSv1.0</string>
</dict>
</dict>
</dict>
这是一个测试TLS的控制台命令:
nscurl --ats-diagnostics --verbose https://xxxxxxxxx
这里能自动测试哪种key能通过,随便找个https的网站试一下吧。
- 最后,这个问题困扰了我一天多。在网上各种找,尝试种种方案,一直报1200的错误。然后,然后我就打开苹果开发者官网搜了下proxy。我只想说What the F···。一般来说官方文档是了解一门技术的最好方式,为什么我才想起呢?
- 再遇到这种牛角尖问题:
- 借助官方文档!!!
- 借助官方文档!!!
- 借助官方文档!!!
附上connectionProxyDictionary
keys 参见Table 3-7
https://developer.apple.com/library/content/documentation/Networking/Conceptual/SystemConfigFrameworks/SC_UnderstandSchema/SC_UnderstandSchema.html
网友评论