网络代理的用途广泛,常用于代理爬虫,代理VPN ,代理注入等。使用网络 代理能够将入侵痕迹进一步减少,能够突破自身IP的访问限制,提高访问速度, 以及隐藏真实IP ,还能起到一定的防止攻击的作用。下面将介绍如何使用Python 代理进行访问,以及代理爬虫的使用。
Python的代理有多种用法,本节介绍常见的几种:Urllib代理、requests代 理。
Urllib代理的设置包括设置代理的地址和端口,访问测试的网址进行测试,会 返回访问的IP地址,如果返回的IP是代理IP ,则说明是通过代理访问的。示例代 码如下:
from urllib.error import URLError from urllib.request import ProxyHandler,build_opener proxy='127.0.0.1 :1087' # 代理地址 proxy_handler=ProxyHandler({ 'http ' : 'http:// '+proxy, 'https ' : 'https:// '+proxy }) opener=build_opener(proxy_handler) try: response = opener .open( 'http://httpbin .org/get ') print(response .read() .decode( 'utf-8 ')) except URLError as e: print(e .reason) |
# |
测试IP的网址 |
运行结果如下所示:
requests代理设置包括设置代理的IP地址和端口,访问测试页面,通过测试页 面的返回值判断是否为通过代理访问。示例代码如下:
# requests代理设置 import requests proxy='127.0.0.1 :1087' # 代理地址 proxies={ 'http ' : 'http:// '+proxy, 'https ' : 'https:// '+proxy } try: response=requests.get('http://httpbin.org/get ',proxies=proxies) print(response .text) except requests .exceptions .ConnectionError as e: print( 'error: ',e .args) |
运行结果与Urllib代理相同。 付费代理的使用方法与普通代理的一样,仅仅需要修改proxy的值,在代理IP 地址前加上“用户名:密码@” 即可。示例代码如下:
|
proxy= 'username:password@IP:port ' |
下面来看一个代理应用的案例:爬取某电影评论。 首先,找到一个获取电影评论的接口,如下所示:
|
http://m .×××××× .com/mmdb/comments/movie/1200486 .json? v =yes&offset=
0&startTime=2018-010-20%2022%3A25%3A03
分析一下这个接口的参数信息,可以发现1200486是指电影的唯一识别ID。 startTime对应获取到的评论截止时间,从截止时间向前获取15条评论。 分析好后就可以开始编写脚本了,步骤如下: 1)使用requests库的代理方法进行接口访问,代码如下: |
'127.0.0.1 :1087' = { 'http ' : 'http:// ' + proxy, 'https ' : 'https:// ' + proxy } |
2)设置代理地址和端口,让之后的链接都通过此代理来绕过可能存在的反 爬虫工具: |
headers = { 'User-Agent ' : 'Mozilla/5 .0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537 .36 (KHTML, like Gecko) Chrome/76 .0 .3809 .100 Safari/537 .36 ' } |
3)设置一个UA ,也可以设置多个UA ,每次访问时随机抽取UA来避免被检 测:
|
try: print(url) response = requests .get(url,headers=headers, proxies=proxies, timeout=3) if response .status_code == 200: print(response .text) return response .text return None except requests .exceptions .ConnectionError as e: print( 'error: ', e .args) |
4)访问接口URL并判断访问是否成功,若成功,则将数据返回,效果如下 所示: |
5)可以看到,已经成功获取到了数据,但是数据的格式还是原始接口返回 的格式,里面的数据并非都是我们想要的数据。所以再写一个数据优化的方法, 传入原始数据进行处理,并将处理后的结果返回: |
def parse_data(html) :
data = json .loads(html)[ 'cmts ']
comments = []
for item in data:
comment = {
'id ' : item[ 'id '],
'nickName ' : item[ 'nickName '],
'cityName ' : item[ 'cityName '] if 'cityName ' in item else ' ',
'content ' : item[ 'content '] .replace( '\n ', ' ', 10),
'score ' : item[ 'score '],
'startTime ' : item[ 'startTime ']
}
comments .append(comment)
return comments
运行效果如下所示: |
6)可以看到,数据已经处理完成了,接下来进行循环和保存。获取评论时 应该从当前时间向前爬取,所以先获取当前时间: |
start_time = date time .now() .strftime( '%Y-%m-%d %H:%M:%S ') |
7)设置截止时间为上映时间,再往前就没有评论了,循环爬取到截止时间 点后停止爬取:
|
end_time = '上映时间 ' |
8)需要循环判断获取的时间是否小于截止的时间点,小于则代表是最早的 评论,爬取完成: |
while start_time > end_time: url = 'http://m .×××××× .com/mmdb/comments/movie/1203084 .json? v =yes&offset=0&startTime= ' + start_time .replace( ' ', '%20 ') try: html = get_data(url) # 获取数据 except Exception as e: time .sleep(0 .5) html = get_data(url) else: |
9)每次循环获取的末尾评论时间为下次开始时间时,继续向前获取,再将 数据进行处理并保存即可:
|
comments = parse_data(html)
print(comments)
start_time = comments[14][ 'startTime '] # 获得末尾评论的时间
start_time = date time .s trptime(start_time, '%Y-%m-%d %H:%M:%S ') +
timedelta(seconds=-1)
start_time = date time .strftime(start_time, '%Y-%m-%d %H:%M:%S ')
for item in comments:
with open( 'data .txt ', 'a ', encoding= 'utf-8 ') as f : f.write(str(item[ 'id '])+ ', '+item[ 'nickName '] + item[ 'cityName '] + ', ' + item[ 'content '] +
+
+
使用代理爬取数据便完成了,效果如下所示: