nodejs爬虫如何设置动态ip以及userAgent
nodejs爬虫如何设置动态ip以及userAgent
前言
在写nodejs爬虫的过程中,原网站可能会对某一时间段内集中访问该页面的ip进行封杀。那么如何动态设置每次爬取使用的ip地址以及浏览器头部信息呢?
动态userAgent
这是我收集到的常用的浏览器头部信息,每次爬取的时候从中随机选取一个,并使用superAgent设置请求头部的User-Agent字段就好了。
userAgent.js
const userAgents = [
'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.12) Gecko/20070731 Ubuntu/dapper-security Firefox/1.5.0.12',
'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Acoo Browser; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506)',
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.20 (KHTML, like Gecko) Chrome/19.0.1036.7 Safari/535.20',
'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.8) Gecko Fedora/1.9.0.8-1.fc10 Kazehakase/0.5.6',
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.71 Safari/537.1 LBBROWSER',
'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0) ,Lynx/2.8.5rel.1 libwww-FM/2.14 SSL-MM/1.4.1 GNUTLS/1.2.9',
'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)',
'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; QQBrowser/7.0.3698.400)',
'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E)',
'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0b13pre) Gecko/20110307 Firefox/4.0b13pre',
'Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; fr) Presto/2.9.168 Version/11.52',
'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.12) Gecko/20070731 Ubuntu/dapper-security Firefox/1.5.0.12',
'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; LBBROWSER)',
'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.8) Gecko Fedora/1.9.0.8-1.fc10 Kazehakase/0.5.6',
'Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527+ (KHTML, like Gecko, Safari/419.3) Arora/0.6',
'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; QQBrowser/7.0.3698.400)',
'Opera/9.25 (Windows NT 5.1; U; en), Lynx/2.8.5rel.1 libwww-FM/2.14 SSL-MM/1.4.1 GNUTLS/1.2.9',
'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'
]
module.exports = userAgents
app.js
import request from 'superagent'
import userAgents from '../src/userAgent'
async function doRequest(){
let userAgent = userAgents[parseInt(Math.random() * userAgents.length)]
request.get('http://www.xxx.com')
.set({ 'User-Agent': userAgent })
.timeout({ response: 5000, deadline: 60000 })
.end(async(err, res) => {
// 处理数据
})
}
动态ip
设置动态IP需要用到一个superagent插件—superagent-proxy,除此之外为了避免每次爬取时都去获取一次动态IP的列表,我将爬取到的动态IP列表存放在redis中,并设置10分钟的过期时间。数据过期之后再重新发送获取动态IP的请求。
ps: 这里我使用的动态IP是爬虫网络科技公司提供的免费代理,因为免费所以难免会有些缺陷。有时候使用他的代理ip并不能访问得通,我在后面会做单独的处理。
package.json
{
"name": "xxx",
"version": "1.0.0",
"description": "xxx",
"main": "arf.js",
"scripts": {
"arf": "nodemon src/app.js --exec babel-node --config package.json"
},
"keywords": [
"爬虫"
],
"author": "lidikang",
"license": "MIT",
"dependencies": {
"bluebird": "^3.5.1",
"cheerio": "^1.0.0-rc.2",
"eventproxy": "^1.0.0",
"mongoose": "^4.13.6",
"mongoose-findorcreate": "^2.0.0",
"progress": "^2.0.0",
"redis": "^2.8.0",
"superagent": "^3.8.1",
"superagent-proxy": "^1.0.2"
},
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-stage-2": "^6.24.1",
"nodemon": "^1.12.4"
},
"nodemonConfig": {
"ignore": [
"ips.json",
"docs/*"
],
"delay": "2500"
}
}
app.js
import request from 'superagent'
import requestProxy from 'superagent-proxy'
import redis from 'redis'
// superagent添加使用代理ip的插件
requestProxy(request)
// redis promise化
bluebird.promisifyAll(redis.RedisClient.prototype)
bluebird.promisifyAll(redis.Multi.prototype)
// 建立mongoose和redis连接
const redisClient = connectRedis()
/**
* 初始化redis
*/
function connectRedis() {
let client = redis.createClient(config.REDIS_URL)
client.on("ready", function(err) {
console.log('redis连接 √')
})
client.on("error", function(err) {
console.log(`redis错误,${err} ×`);
})
return client
}
/**
* 请求免费代理,读取redis,如果代理信息已经过期,重新请求免费代理请求
*/
async function getProxyIp() {
// 先从redis读取缓存ip
let localIpStr = await redisClient.getAsync('proxy_ips')
let ips = null
// 如果本地存在,则随机返回其中一个ip,否则重新请求
if (localIpStr) {
let localIps = localIpStr.split(',')
return localIps[parseInt(Math.random() * localIps.length)]
} else {
let ipsJson = (await request.get('http://api.pcdaili.com/?orderid=888888888&num=100&protocol=1&method=1&an_ha=1&sp1=1&sp2=1&format=json&sep=1')).body
let isRequestSuccess = false
if (ipsJson && ipsJson.data.proxy_list) {
ips = ipsJson.data.proxy_list
isRequestSuccess = true
} else {
ips = ['http://127.0.0.1']
}
// 将爬取结果存入本地,缓存时间10分钟
if (isRequestSuccess) {
redisClient.set("proxy_ips", ips.join(','), 'EX', 10 * 60)
}
return ips[parseInt(Math.random() * ips.length)]
}
}
async function doRequest(){
let userAgent = userAgents[parseInt(Math.random() * userAgents.length)]
let ip = await getProxyIp()
let useIp = 'http://' + ip
request.get('http://www.xxx.com')
.set({ 'User-Agent': userAgent })
.timeout({ response: 5000, deadline: 60000 })
.proxy(ip)
.end(async(err, res) => {
// 处理数据
})
}
之前说爬虫网络科技的免费ip有些缺陷—代理成功率有些低。这点必须想办法去修复,原理其实很简单,既然一次不成功那我就换个IP再试,直到成功了我才去开始执行解析html的逻辑
async function doRequest(){
let userAgent = userAgents[parseInt(Math.random() * userAgents.length)]
let ip = await getProxyIp()
let useIp = 'http://' + ip
request.get('http://www.xxx.com')
.set({ 'User-Agent': userAgent })
.timeout({ response: 5000, deadline: 60000 })
.proxy(ip)
.end(async(err, res) => {
if (err) {
console.log(`爬取页面失败,${err},正在重新寻找代理ip... ×`)
// 如果是代理ip无法访问,另外选择一个代理
doRequest('http://' + await getProxyIp(), userAgents[parseInt(Math.random() * userAgents.length)])
return
}
// 解析html
console.log('爬取页面 √')
await parseDivision(res.text)
})
}
如果你有啥疑问,欢迎写信到我的邮箱(andyliwr@outlook.com)与我讨论。
nodejs爬虫如何设置动态ip以及userAgent的更多相关文章
- 爬虫平台设置代理ip
首先从国外一个网站爬取了免费的代理ip信息存到mongodb中:接着代码设置: 在爬虫客户端抽象类中添加属性: 设置代理的代码其实就以下几句: firefoxProfile.setPreference ...
- Linux 静态IP动态IP设置
1.设置动态IP ifconfig eth0 192.168.1.12 设置后立即生效,重启机器后就无效了 2.设置静态IP 编辑文件 /etc/sysconfig/network-scripts/i ...
- 路由器中pppoe,动态IP,静态IP的区别
路由器中pppoe,动态IP,静态IP的区别 要把路由器设置得能上网,无非就是设置WAN外网接口连接而已.WAN接口能上网,则连接的电脑就能上网,反之则上不了网.只不过WAN接口往往有pppoe,动态 ...
- Ubuntu 18.04 Server 设置静态IP
一.背景 Netplan是Ubuntu 17.10中引入的一种新的命令行网络配置实用程序,用于在Ubuntu系统中轻松管理和配置网络设置.它允许您使用YAML抽象来配置网络接口.它可与NetworkM ...
- 如何修改静态IP地址和动态IP地址
打开控制面板,一般在电脑的菜单栏能找到,win8和win10可以使用快捷键(win键+X键),找不到的朋友可以搜索一下. 进入到网络和共享中心,点击更改适配器设置. 这里显示的是电脑所以的网络 ...
- win10配置的静态/动态IP和 DNS的方法
1.配置静态IP和DNS netsh interface ip set address name="以太网" source=static addr=192.168.9.145 ma ...
- Windows如何设置动态和静态ip地址
打开控制面板,一般在电脑的菜单栏能找到,win8和win10可以使用快捷键(win键+X键),找不到的朋友可以搜索一下. 进入到网络和共享中心,点击更改适配器设置. 这里显示的是电脑所以的网络 ...
- Xshell 连接虚拟机OS Linux 设置静态ip ,网络配置中无VmWare8 的解决办法
前序:最近开始研究Hadoop平台的搭建,故在本机上安装了VMware workstation pro,并创建了Linux虚拟机(centos系统),为了方便本机和虚拟机间的切换,准备使用Xshell ...
- nodejs爬虫设置动态userAgent
动态 userAgent 这是我收集到的常用的浏览器头部信息,每次爬取的时候从中随机选取一个,并使用 superAgent 设置请求头部的 User-Agent 字段就好了. userAgent.js ...
随机推荐
- session有效期设置的两种方式
/**session有效期设置的两种方式: * 1.代码设置:session.setMaxInactiveInterval(30);//单位:秒.30秒有效期,默认30分钟. * 2.web.xml中 ...
- myEclipse项目部署点击Finish按钮没反应
-- 问题描述:myEclipse项目部署点击Finish按钮没反应. -- 问题原因:Tomcat没有不熟JDK. -- 解决办法:window->preferences->servic ...
- Spring Boot 配置多源的 RabbitMQ
简介 MQ 是开发中很平常的中间件,本文讲述的是怎么在一个Spring Boot项目中配置多源的RabbitMQ,这里不过多的讲解RabbitMQ的相关知识点.如果你也有遇到需要往多个RabbitMQ ...
- opencv——图像掩码操作
使用opencv通过掩码去扣取图像中感兴趣的区域 步骤: 1.读取一张图片 2.转换颜色格式为hsv 3.设置要扣取区域颜色的上下门限 4.从原始图像中获取感兴趣区域的掩码 5.使用掩码和原始图像做云 ...
- mysqlbinlog 恢复数据到任意时间点
创建表,插入数据. ``` mysql> create database binlog; mysql> create table bt(id int); mysql> insert ...
- ant安装(Windows)
ant安装(Windows) ant 下载之前参考一下官网的ant与java版本依赖 1. 下载地址 2. 解压与配置 1. 下载地址 ant官网 所有版本 2. 解压与配置 java版本:1.8.0 ...
- 介于JAVAswing和Socket写的聊天室
在厦门的第一阶段给我们复习了JAVASE基础,第一阶段的小玩具叫我们自选题材,我自己选了聊天室这个内容,这个小玩具无论是线程,还是网络编程,都会涉及到,比较有综合性,所以我选了这个: 这是我的包体结构 ...
- HashMap扩容死循环问题
原文:https://blog.csdn.net/Leon_cx/article/details/81911223 下面我们来模拟一下多线程场景下扩容会出现的问题: 假设在扩容过程中旧hash桶中有一 ...
- 调试中行支付demo
用eclipse调试中行支付demo,本来报错. 让我同学帮我远程看了下,他删了服务器,又添加服务器,然后竟然可以运行了,牛逼! 原来报错: at java.net.URLClassLoader$1. ...
- 洛谷 P1816 忠诚题解
题目描述 老管家是一个聪明能干的人.他为财主工作了整整10年,财主为了让自已账目更加清楚.要求管家每天记k次账,由于管家聪明能干,因而管家总是让财主十分满意.但是由于一些人的挑拨,财主还是对管家产生了 ...