Python爬虫请求头、请求代理以及cookie操作

·爬虫程序urllib2模块底层操作;

·请求头的设置和添加;

·请求代理的种类和类型;

·关于cookie的操作(手动添加/程序自动获取)

一、爬虫底层操作和请求头的设置

1.demo01_爬虫底层操作

虽然urllib2模块是爬虫的底层操作,但并不是程序的底层操作,在其内部的urlopen函数也是有自己封装的内容,实则参数为一个request即请求对象。

# -*- coding:utf-8 -*-
# 引入需要的模块
import urllib2

# 定义url
url='https://www.taobao.com'

# 根据url构建请求对象
request=urllib2.Request(url)

# 使用urllib2urlopen函数发送请求对象
response=urllib2.urlopen(request)

print response.read()

2.demo02_请求头的设置

客户端在浏览器发送请求给服务器时,会携带请求头,在请求头中有一个User-Agent属性.

User-Agent:用户代理 User Agent,是指浏览器,它的信息包括硬件平台、系统软件、应用软件和用户个人偏好。在X.400电子系统中,用户代理是一种对数据打包、创造分组头,以及编址、传递消息的部件。用户代理并不是仅指浏览器,还包括搜索引擎。

User-Agent其实就是代表用户访问服务器数据的工具,一般情况下,User-Agent是浏览器发起请求时,请求头中包含的数据,主要描述了发送请求的浏览器的版本及内核,操作信息内容等。

①请求头中的数据可以被重新设置。②请求头中可以字典的形式传送自定义数据。

了解都有哪些User-agent

设置请求头

Mozilla/5.0(Macintosh;U;IntelMacOSX10_6_8;en-us)AppleWebKit/534.50(KHTML,likeGecko)Version/5.1Safari/534.50

Mozilla/5.0(Windows;U;WindowsNT6.1;en-us)AppleWebKit/534.50(KHTML,likeGecko)Version/5.1Safari/534.50

Mozilla/5.0(compatible;MSIE9.0;WindowsNT6.1;Trident/5.0;

Mozilla/4.0(compatible;MSIE8.0;WindowsNT6.0;Trident/4.0)

Mozilla/4.0(compatible;MSIE7.0;WindowsNT6.0)

Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1)

Mozilla/5.0(WindowsNT6.1;rv:2.0.1)Gecko/20100101Firefox/4.0.1

Opera/9.80(Macintosh;IntelMacOSX10.6.8;U;en)Presto/2.8.131Version/11.11

Opera/9.80(WindowsNT6.1;U;en)Presto/2.8.131Version/11.11

Mozilla/5.0(Macintosh;IntelMacOSX10_7_0)AppleWebKit/535.11(KHTML,likeGecko)Chrome/17.0.963.56Safari/535.11

Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1;Maxthon2.0)

Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1;TencentTraveler4.0)

Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1)

Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1;TheWorld)

Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1;Trident/4.0;SE2.XMetaSr1.0;SE2.XMetaSr1.0;.NETCLR2.0.50727;SE2.XMetaSr1.0)

Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1;360SE)

 
# -*- coding:utf-8 -*-
# 引入需要的模块
import urllib2
import random

# 定义url
url = 'https://www.taobao.com'
# 多个user_agent列表
ua = ['Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; 360SE)',
      'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; SE 2.X MetaSr 1.0; SE 2.X MetaSr 1.0; .NET CLR 2.0.50727; SE 2.X MetaSr 1.0)',
      'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11']

# 随机选取一个user_agent
user_agent = random.choice(ua)
# 定义请求头
my_header = {'User-agent': user_agent}


# 或者使用函数为请求头增加数据
# request=urllib2.Request(url)
# request.add_header('header',my_header)
# 根据url构建请求对象,并设置请求头(设置请求头信息,就是设置浏览器版本和内核信息,让爬虫程序伪装成客户端浏览器)
request = urllib2.Request(url, headers=my_header)

# 使用urllib2urlopen函数发送请求对象
response = urllib2.urlopen(request)

print response.read()
 

二、请求方式

1.get请求方式:访问百度搜索

一般情况下都是在Url地址中直接拼接查询字符串的get参数,完成数据的操作

注意:url地址中的中文,在时下较新的浏览器中可以正常处理,但是不一定兼容版本较旧的浏览器,中文的处理一定要进行编码操作

通过urllib.urlencode()的方式,将一个字典数据编辑成k=v形式的数据作为参数拼接给url地址

# -*- coding:utf-8 -*-

'''
get方式访问百度搜索
'''
# 引入需要的模块
import urllib2
import urllib
import random


# 多个user_agent列表
ua = ['Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; 360SE)',
      'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; SE 2.X MetaSr 1.0; SE 2.X MetaSr 1.0; .NET CLR 2.0.50727; SE 2.X MetaSr 1.0)',
      'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11']

# 随机选取一个user_agent
user_agent = random.choice(ua)
# 定义请求头
my_header = {'User-agent': user_agent}
# 定义url,根据抓包工具分析得到的访问路由,由于参可变,所以后面以拼接的方式将参数拼接上来
url = 'https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=0&rsv_idx=1&tn=baidu&'
get_params=raw_input('请输入要搜索的内容:')
# kw='',即浏览器中url路径参数形式
data={'wd':get_params}
# 上面data为字典形式,通过urllib模块的urlencode函数可以将输入的中文编码,并将字典形式转换为k=v# 便于在url中显示,以获取数据
data=urllib.urlencode(data)
# 将访问路由url的固定部分(url)和可变参数(data)拼接成完成的full_url
full_url=url+data

# 根据url和请求头创建一个请求对象
request=urllib2.Request(full_url,headers=my_header)
response = urllib2.urlopen(request)
content=response.read()
with open('qiku.html','w') as f:
    f.write(content)

print (content)

2.post方式访问有道翻译

1. urllib2发送post请求

定义发送的数据

form_data = {}

将发送的数据转换成字符串编码

data = urllib.urlencode(form_data)

构建Request对象时,如果给data参数赋值,默认发送POST请求

request = urllib2.Request(url, data=data)

urllib2.urlopen(request)# 发送出去的就是POST请求

发送POST请求以及POST请求附带的参数

2. 反[反爬虫]操作

l 确认目标url地址的数据,执行了反爬虫机制!

通过抓包工具,得到目标url地址的具体访问路径Path以及附带的参数,然后将这些数据直接在爬虫程序中进行赋值添加,如果此时访问失败,目标url地址的数据可能执行了反爬虫机制!如~有道在线翻译~我们将所有的请求数据原封不动的添加到爬虫程序中,但是得到了错误的结果:{errorCode:50},有道在线翻译执行了反爬虫机制

l 反[反爬虫]步骤

分析请求中的数据

追踪数据的来源

伪造数据

反机制成功!


 

# -*- coding:utf-8 -*-
'''
访问url:http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule
请求参数:
    i hello
    from AUTO
    to AUTO
    smartresult dict
    client fanyideskweb
    salt 1515466801319
    sign 78f918a6eb55b77d633cba89bd8385da
    doctype json
    version 2.1
    keyfrom fanyi.web
    action FY_BY_REALTIME
    typoResult false
'''
# 引入需要的模块
import urllib2
import urllib
import random




#######################################################################
import time
E = "fanyideskweb"
# salt盐值
r = str(time.time()*1000 + random.randint(1,10))
# 确定翻译的数据
n = raw_input("请输入要翻译的词语:")
# 确定加密的混淆吗
O = "aNPG!!u6sesA>hBAW1@(-"
# 确定sign参数
import hashlib
sign = hashlib.md5(E + n + r + O).hexdigest()


# 设置有道在线翻译的请求头
headers = {
    #"Host": "fanyi.youdao.com",
    #"Connection": "keep-alive",
    #"Content-Length": "200",
    #"Accept": "application/json, text/javascript, */*; q=0.01",
    #"Origin": "http://fanyi.youdao.com",
    #"X-Requested-With": "XMLHttpRequest",
    #"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
    "Referer": "http://fanyi.youdao.com/",
    # "Accept-Encoding": "gzip, deflate",
    #"Accept-Language": "zh-CN,zh;q=0.8",
    "Cookie": "OUTFOX_SEARCH_USER_ID_NCOO=2075764580.1728754; [email protected]; JSESSIONID=aaaxakcpWa-oo8wK72ydw; fanyi-ad-id=39535; fanyi-ad-closed=1; ___rl__test__cookies=1515468614442i=hell&from=AUTO&to=AUTO&smartresult=dict&client=fanyideskweb&salt=1515468614446&sign=710df1dcc70f91c1b04e795a34704c8e&doctype=json&version=2.1&keyfrom=fanyi.web&action=FY_BY_REALTIME&typoResult=false"
}
#######################################################################


# 定义ua
ua = [
    "Mozilla/5.0(Macintosh;U;IntelMacOSX10_6_8;en-us)AppleWebKit/534.50(KHTML,likeGecko)Version/5.1Safari/534.50",
    "Mozilla/5.0(Windows;U;WindowsNT6.1;en-us)AppleWebKit/534.50(KHTML,likeGecko)Version/5.1Safari/534.50",
    "Mozilla/5.0(compatible;MSIE9.0;WindowsNT6.1;Trident/5.0;",
    "Mozilla/4.0(compatible;MSIE8.0;WindowsNT6.0;Trident/4.0)",
    "Mozilla/4.0(compatible;MSIE7.0;WindowsNT6.0)",
]
# 随机获取一个ua
user_agent = random.choice(ua)


# 定义url地址
url = "http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule"


# 定义表单数据
form_data = {
    "i": n,# 要翻译的词语
    "from": "AUTO", # 词语的翻译之前的语言
    "to": "AUTO", # 词语翻译之后的语言
    "smartresult": "dict", # 数据类型
    "client": "fanyideskweb", # 客户端标识
    "salt": r, # ~~~~可能是~~~时间
    "sign": sign,# ~~~~可能是~~~~md5
    "doctype": "json", # 数据类型
    "version": 2.1,# 版本号
    "keyfrom": "fanyi.web",# 关键字
    "action": "FY_BY_REALTIME",# 行为描述
    "typoResult": False # 结果类型
}
data = urllib.urlencode(form_data)


# 封装请求对象
request = urllib2.Request(url, data=data, headers=headers)
request.add_header("User-agent", user_agent)


# 发送请求获取响应数据
response = urllib2.urlopen(request)


# 打印展示数据
print(response.read())

3.爬取百度图片

确定目标地址[数据访问的真实路径path]

确定参数的含义[通过手工更新参数数据,确定参数的用途]

爬取百度图片页面中展示的图片列表[json字符串数据]【第一次爬取数据】

筛选图片链接[确定图片的规则(http:….jpg/.png),正则表达式筛选目标数据]

img_re_list = re.findall(‘pattern’, content)

循环针对每个图片进行数据爬取【第二次循环爬取数据】

response = urllib2.urlopen(img_url) 

with->open() as f->f.write(response.read())

# -*- coding:utf-8 -*-
# 引入需要的模块
import urllib
import urllib2
import re

# 定义访问路由
url = 'https://image.baidu.com/search/acjson?'

# 定义请求头
my_header = {
    #'Host': 'image.baidu.com',
    #'Connection': 'keep-alive',
    #'Accept': 'text/plain, */*; q=0.01',
    #'X-Requested-With': 'XMLHttpRequest',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36',
    'Referer': 'https://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fm=result&fr=&sf=1&fmq=1515495630056_R&pv=&ic=0&nc=1&z=&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&word=%E6%B8%85%E9%A3%8E',
    #'Accept-Encoding': 'gzip, deflate, br',
    #'Accept-Language': 'zh-CN,zh;q=0.9',
    'Cookie': 'BDqhfp=%E6%B8%85%E9%A3%8E%26%260-10-1undefined%26%26766%26%262; BAIDUID=01316FFFC8551DCE978112EC7D40746A:FG=1; BIDUPSID=01316FFFC8551DCE978112EC7D40746A; PSTM=1515224694; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; BDRCVFR[X_XKQks0S63]=mk3SLVN4HKm; userFrom=www.so.com; firstShowTip=1; BDRCVFR[-pGxjrCMryR]=mk3SLVN4HKm; cleanHistoryStatus=0; BDRCVFR[dG2JNJb_ajR]=mk3SLVN4HKm; indexPageSugList=%5B%22%E6%B8%85%E9%A3%8E%22%2C%22%E5%94%AF%E7%BE%8E%22%2C%22%E4%BD%A0%22%2C%22%E5%8F%91%22%2C%22%E7%BE%8E%E5%A5%B3%22%2C%22%E5%94%AF%E7%BE%8E%E5%9B%BE%E7%89%87%E5%A4%A7%E5%85%A8%22%5D'
}

form_data={
    'tn':'resultjson_com',
    'ipn':'rj',
    'word':'清风',
    'pn':90,
    'rn':30,
}
form_data=urllib.urlencode(form_data)
# 定义请求对象
request = urllib2.Request(url+form_data, headers=my_header)

# 发送请求
response = urllib2.urlopen(request)

content = response.read()

url_list=re.findall('"thumbURL":"(.*?)"', content)
print(url_list)

for url in url_list:
    print("保存图片%s" % url)
    request = urllib2.Request(url, headers=my_header)
    response = urllib2.urlopen(request)
    img_url = url.replace("/", "_")
    with open('bd_img/' + img_url[-50:], "wb") as f:
        f.write(response.read())
    print("图片%s保存完成" % img_url)

三、自定义opener对象——爬虫底层操作对象

1.为什么要自定义opener对象

python内置模块提供了通用爬虫可以操作的Opener对象,但是如果一旦涉及到自定义的针对各种特定环境的操作,python内置的Opener对象就不能满足我们的需要了,例如客户端和服务器一直在做斗争的爬虫~发爬虫机制:

爬虫~反爬虫~服务器为反爬虫的变态做法:

1.封锁IP

对应策略:反[反爬虫(IP封锁)]:使用代理服务器(肉机),如果使用代理服务器操作的情况下,python内置的opener对象就不能满足我们的需要了

2.需要会话跟踪才能访问的URL地址[session-cookie]

对应策略(对cookie的操作):

①请求中包含cookie数据,可以手工抓包,将cookie数据直接添加到请求头中,实现模拟登陆的情况!手工操作cookie数据~如果服务器出现了即时cookie数据更新,手工操作cookie的的方式就不会太友好了!~python内置的opener对象,不能满足我们直接操作cookie的需求。

关于代理服务器:

代理服务器的类型:

透明代理:服务器能清楚的查看某个IP地址的客户端通过某个IP地址的代理服务器发送了代理请求

匿名代理:服务器能清楚的查看到某个IP地址的代理服务器发起了代理请求,但是查看不到是哪个具体的客户端

高匿代理:服务器分不清这次请求是否代理发送

常见的代理服务器:

免费:提供了代理ip地址和端口port可以免费使用,但是网速一般较慢,存活时间没有保障

收费:提供了代理ip地址和端口port,并且结合账号+密码登录之后才能连接使用,收费的代理~稳定、网速一般较快、动态IP地址跳跃等等

在程序中对于cookie的操作,这就需要我们自定义opener对象,使用python内置了cookielib模块,可以针对请求cookie进行读写操作

实现在程序中自动获取cookie

CookieJar核心模块

FileCookieJar核心模块(继承自上面)

MozillaCookieJar核心模块(继承自上面)

cookie数据直接操作

cookie数据读写操作

2.简单的自定义opener对象的例子

# -*- coding:utf-8 -*-
'''
自定义opener对象的小程序,以爬取"https://www.taobao.com"为例
'''
# 引入需要的模块
import urllib2

# 定义访问路由
url='https://www.taobao.com'
# 定义请求头
my_header={'User-Agent':'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; 360SE)'}

# 根据请求地址,定义请求对象
request=urllib2.Request(url,headers=my_header)

# 创建一个自定义的handler对象,操作控制httphandler对象
http_handler=urllib2.HTTPHandler()

# 构建一个opener对象
http_opener=urllib2.build_opener(http_handler)

# 发送请求
response=http_opener.open(request)
print response.read()
# -*- coding:utf-8 -*-
'''
自定义opener对象的小程序,以爬取"https://www.taobao.com"为例
'''
# 引入需要的模块
import urllib2

# 定义访问路由
url='https://www.taobao.com'
# 定义请求头
my_header={'User-Agent':'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; 360SE)'}

# 根据请求地址,定义请求对象
request=urllib2.Request(url,headers=my_header)

# 创建一个自定义的handler对象,操作控制httphandler对象
http_handler=urllib2.HTTPHandler()

# 构建一个opener对象
http_opener=urllib2.build_opener(http_handler)

# 发送请求
response=http_opener.open(request)
print response.read()

3.创建可以操作代理服务器的opener对象

# -*- coding:utf-8 -*-
'''
创建可以操作代理服务器的开锁人(opener对象)
代理服务器包括收费代理和免费代理,分为透明、匿名和高匿三种不同程度和类型的代理,这里以免费代理为例。直接在网上搜索免费代理,可以搜到ip和端口
使用收费代理与免费代理相似,只是要加上登录名和密码

免费:提供了代理ip地址和端口port可以免费使用,但是网速一般较慢,存活时间没有保障
使用形式:"http":"ip地址:port端口"

收费:提供了代理ip地址和端口port,并且结合账号+密码登录之后才能连接使用,收费的代理~稳定、网速一般较快、动态IP地址跳跃等等
使用形式:"http":"账户名:密码@ip地址:port端口"
'''
# 引入需要的模块
import urllib2

# 定义访问的url地址
url = 'https://www.taobao.com'
# 定义请求头
my_header = {'User-Agent': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; 360SE)'}
# 根据定义的访问地址,创建请求对象
request = urllib2.Request(url, headers=my_header)
# 创建可以操作代理服务器的操作对象,这里ProxyHandler是操作代理服务器的操作对象,括号中可直接填写代理服务器的信息
proxy_handler=urllib2.ProxyHandler({"http":"110.73.8.153:8123"})
# proxy_handler = urllib2.ProxyHandler({"http": "admin:[email protected]:8123"})
# 根据代理服务器的操作对象,创建opener对象(开锁人)
proxy_opener=urllib2.build_opener(proxy_handler)
response=proxy_opener.open(request)
print response.read()

4.对于opener对象的重新定义,使用python内置的cookielib模块,测试学习程序对cookie的操作。

# -*-coding:utf-8 -*-
# 引入需要的模块
import urllib2
import cookielib


# 定义访问的url地址
url = 'https://www.taobao.com'
# 定义请求头
my_header = {'User-Agent': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; 360SE)'}

request=urllib2.Request(url,headers=my_header)
# 定义一个cookie核心对象
cookie=cookielib.CookieJar()
# 自定义一个handler对象,可以操作cookie
cookie_handler=urllib2.HTTPCookieProcessor(cookie)

# 定义opener
cookie_opener=urllib2.build_opener(cookie_handler)
# 发送请求
response=cookie_opener.open(request)

# 这是一个小程序,专门用于测试cookielib模块对于cookie数据的操作
# 重点不在于获取爬取的数据,而是在于cookie中的数据
for item in cookie:
    print("%s-%s" % (item.name, item.value))
    # "{} - {}".format("hello", "world")
    
    '''打印结果:thw-cn
    
    '''
 
# -*-coding:utf-8 -*-
# 引入需要的模块
import urllib2
import cookielib


# 定义访问的url地址
url = 'https://www.taobao.com'
# 定义请求头
my_header = {'User-Agent': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; 360SE)'}

request=urllib2.Request(url,headers=my_header)
# 定义一个cookie核心对象
cookie=cookielib.CookieJar()
# 自定义一个handler对象,可以操作cookie
cookie_handler=urllib2.HTTPCookieProcessor(cookie)

# 定义opener
cookie_opener=urllib2.build_opener(cookie_handler)
# 发送请求
response=cookie_opener.open(request)

# 这是一个小程序,专门用于测试cookielib模块对于cookie数据的操作
# 重点不在于获取爬取的数据,而是在于cookie中的数据
for item in cookie:
    print("%s-%s" % (item.name, item.value))
    # "{} - {}".format("hello", "world")
    
    '''打印结果:thw-cn
    
    '''

4.对于opener对象的重新定义,使用python内置的cookielib模块,完成程序对于cookie的操作(直接获取并保存)

# -*-coding:utf-8 -*-
# 引入需要的模块
import urllib2
import cookielib

# 定义访问的url地址
url = 'https://www.taobao.com'
# 定义请求头
my_header = {'User-Agent': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; 360SE)'}

# 定义请求对象
request=urllib2.Request(url,headers=my_header)
# 获取cookie对象,使用MozillaCookieJar可以直接定义将cookie保存所在的文件名及位置
cookie=cookielib.MozillaCookieJar("demo09.txt")
# 定义操作cookie的对象
cookie_handler=urllib2.HTTPCookieProcessor(cookie)
# 定义opener
cookie_opener=urllib2.build_opener(cookie_handler)
# 发送请求
response=cookie_opener.open(request)
# 保存cookie数据
cookie.save()


'''

文件demo09.txt的内容如下:
# Netscape HTTP Cookie File
# http://curl.haxx.se/rfc/cookie_spec.html
# This is a generated file!  Do not edit.

.taobao.com    TRUE   /  FALSE  1547039357 thw    cn

'''
 

5.对于opener对象的重新定义,使用python内置的cookielib模块,完成程序对于cookie的操作(直接操作使用上一步获取的cookie)

# -*-coding:utf-8 -*-
# 引入需要的模块
import urllib2
import cookielib

# 定义访问的url地址
url = 'https://www.taobao.com'
# 定义请求头
my_header = {'User-Agent': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; 360SE)'}

# 定义请求对象
request=urllib2.Request(url,headers=my_header)
# 获取cookie对象,使用MozillaCookieJar,若需要保存cookie数据,则括号中写文件名,若是获取cookie数据,则不写
cookie=cookielib.MozillaCookieJar()
# 下载cookie数据
cookie.load('demo09.txt')
# 创建Handler操作对象
cookie_handler = urllib2.HTTPCookieProcessor(cookie)
# 创建opener对象
cookie_opener = urllib2.build_opener(cookie_handler)

# 访问目标地址
response = cookie_opener.open(request)

print(response.read())

猜你喜欢

转载自blog.csdn.net/huaidan1469/article/details/81195639
今日推荐