反反爬虫补充
为了更好的伪装成浏览器,增强爬虫的生命力,入门阶段常用的方法就是:设置headers、添加睡眠时间和使用代理ip这三种。设置headers就是让网站服务器认为爬虫是浏览器行为;添加睡眠时间就是为了降低请求频率,请求过于频繁就会被识别出来封IP;为了避免IP被封就可以采用代理IP进行爬虫。
1.设置headers
python可以使用fake_useragent第三方库,来实现随机请求头的设置:
from fake_useragent import UserAgent
ua = UserAgent()
headers = {'User-Agent': ua.random}
这样每次爬虫的时候就会自动携带随机生成的User-Agent。
2.添加睡眠时间
人为浏览网页停留的时间不可能是固定值,所以像time.sleep()这种还是可能被识别出来,可是使每次睡眠的时间变成一个随机值:
import time
sleep_time = random.randint(0,2) + random.random()
time.sleep(sleep_time)
random.randint(0,2)每次取0~2之间的随机整数 ,即0,1,2;random.random()代表取0~1之间的随机小数,两个值相加,每次睡眠的时间是不超过3的随机值,当然也可以把2的值取得更大。
3.代理IP
IP就是用户上网的身份证,因特网上的每台计算机和其它设备都规定了一种地址,叫做"IP 地址"。如果爬取数据量过大或者请求过于频繁,不管什么headers设置和添加睡眠时间都就不管用了,服务器会直接识别出爬虫IP地址,直接封掉,这样就爬不到数据了。IP有免费和收费之分,免费的不稳定,收费的相对稳定比较可靠。比较著名的ip代理网站有:
国内高匿免费HTTP代理IP__第1页国内高匿www.xicidaili.com/nn/
当然还有很多类似的网站,一般进去后选择:
把IP地址和端口号保存下来,注意选择高匿IP,如果使用一般的代理ip服务器端还是能看到爬虫的真实IP。
#把从代理网站收集到的IP和端口号赋值给一个list
proxy = [
'111.29.3.184:8080',
'111.29.3.221:XXXX',
'119.90.126.67:XXXX',
'123.52.97.5:XXXX'
]
#然后设置请求头参数使其可以随机选择一个IP地址
proxies = random.choice(proxy)
#用设置好的随机IP地址去请求网页
response = requests.get(url,headers = headers,proxies = {'http':proxies})
这样,最基础的反反爬虫方法就介绍完了,继续以海投网的陕西省高校宣讲会信息爬虫为例:
import random
import time
import requests
from fake_useragent import UserAgent
from bs4 import BeautifulSoup
proxy = [
'111.29.3.184:8080',
'111.29.3.221:XXXX',
'119.90.126.67:XXXX',
'123.52.97.5:XXXX'
]#输入收集到的高匿ip地址
def get_xuanjiang(url):
headers = {'User-Agent': UserAgent().random}
proxies = random.choice(proxy)
response = requests.get(url,headers = headers,proxies = {'http':proxies})#使用随机的代理IP
print(proxies)#打印目前的ip地址
html = response.text
soup = BeautifulSoup(html, 'lxml')
time_sleep = random.randint(0,2)+random.random()
time.sleep(time_sleep)
print(time_sleep,headers)#打印随机的睡眠时间
companys = soup.find_all('div', class_="text-success company pull-left")
addresss = soup.find_all('a',attrs={'href': True, 'target': True, 'title': True}) # True 可以匹配任何值,如果标签中的属性是变化值就可以这样匹配
dates = soup.find_all('span', class_='hold-ymd')
clicks = soup.find_all('td', class_='cxxt-clicks')
for co, ad, da, cl in zip(companys, addresss, dates, clicks):
company = co.get_text()
address = ad.find('span').contents # 标签的 .contents 属性可以将标签的子节点以列表的方式输出
if len(address) == 0: # 判断输出的列表是否为空
address = 'null'
else:
address = address[0] # 如果不为空,列表中的第一个元素就是地址信息
date = da.get_text()
click = cl.get_text()
print(company, address, date, click)
if __name__ == '__main__':
urls = ['https://xjh.haitou.cc/xa/after/page-{}'.format(i) for i in range(1,16)]
for url in urls:
s = time.time()
get_xuanjiang(url)
e = time.time()
print(e-s)#打印每页爬取耗时
看看运行结果:
可以看到每次请求的ip地址是随机的,user-agent信息也是随机的,这样爬虫的生命力就得到了增强。
### :秉着可持续和谐发展的态度,"Be a responsible web crawler" 是很有必要的,爬取数据尽量不要给人家服务器造成负担(比如:把睡眠时间加长);不要把爬取的数据用于商业行为;不管技术有多牛,不要轻易触碰用户隐私数据。合理、合法、有节制的利用爬虫技术,要不可能给自己带来不必要的麻烦。