在日常爬虫工作中,都需要对爬虫程序进行调试,很多时候会遇到关于ip的错误,特别是新入爬虫的朋友,好好的程序突然报错了?要怎么解决,关于ip访问的错误其实很好解决,但是怎么知道解决好了呢?怎么确定是代理ip的问题呢?今天我们就以java爬虫为例来跟大家详细的聊聊。
代理ip的逻辑在哪里,一般来说,一个scrapy 的项目结构是这样的
scrapydownloadertest # 项目文件夹
│ items.py # 定义爬取结果存储的数据结构
│ middlewares.py # 中间件(可以理解java的过滤器拦截器)
│ pipelines.py # 数据管道,对获取到的数据做操作
│ settings.py # 项目的配置文件
│ init.py # 初始化逻辑
│
├─spiders # 放置 Spiders 的文件夹
│ │ httpProxyIp.py # 爬取到结果后的处理类
│ │ init.py # spider初始化逻辑
scrapy.py
从上图可以发现,代理ip的设置肯定是在发送请求之前就要设置好,那么唯一符合条件的地方就是middlewares.py,所以关于代理的相关逻辑都写在这个里面。直接在其中添加如下代码
Scrapy 内置的 Downloader Middleware 为 Scrapy 供了基础的功能,
定义一个类,其中(object)可以不写,效果一样
class SimpleProxyMiddleware(object):
# 声明一个数组
proxyList = ['http://218.75.158.153:3128','http://188.226.141.61:8080']
# Downloader Middleware的核心方法,只有实现了其中一个或多个方法才算自定义了一个Downloader Middleware
def process_request(self, request, spider):
# 随机从其中选择一个,并去除左右两边空格
proxy = random.choice(self.proxyList).strip()
# 打印结果出来观察
print("this is request ip:" + proxy)
# 设置request的proxy属性的内容为代理ip
request.meta['proxy'] = proxy
# Downloader Middleware的核心方法,只有实现了其中一个或多个方法才算自定义了一个Downloader Middleware
def process_response(self, request, response, spider):
# 请求失败不等于200
if response.status != 200:
# 重新选择一个代理ip
proxy = random.choice(self.proxyList).strip()
print("this is response ip:" + proxy)
# 设置新的代理ip内容
request.mete['proxy'] = proxy
return request
return response
这样就完成了scrapy的代理设置和验证调试。
那应该如何使用动态代理ip呢?
这里使用的是收费的代理ip了,你可以使用亿牛云等云服务商提供的服务,当你注册并缴费之后,会给你提供代理参数,这里直接看代码吧!
import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;
import java.io.IOException;
public class Main {
# 代理服务器(产品官网 www.16yun.cn)
private static final String PROXY_HOST = "t.16yun.cn";
private static final int PROXY_PORT = 31111;
public static void main(String[] args) {
HttpClient client = new HttpClient();
HttpMethod method = new GetMethod("https://httpbin.org/ip");
HostConfiguration config = client.getHostConfiguration();
config.setProxy(PROXY_HOST, PROXY_PORT);
client.getParams().setAuthenticationPreemptive(true);
String username = "16ABCCKJ";
String password = "712323";
Credentials credentials = new UsernamePasswordCredentials(username, password);
AuthScope authScope = new AuthScope(PROXY_HOST, PROXY_PORT);
client.getState().setProxyCredentials(authScope, credentials);
try {
client.executeMethod(method);
if (method.getStatusCode() == HttpStatus.SC_OK) {
String response = method.getResponseBodyAsString();
System.out.println("Response = " + response);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
method.releaseConnection();
}
}
}
最后我们可以通过访问http://httpbin.org/ip来验证代理ip是否使用成功。