'''
4.3 浏览器模拟--headers属性
'''
'''
#有的时候,我们无法爬取一些网页,会出现403错误,因为这些网页为了防止别人恶意
# 采集其信息所以进行了一些反爬虫的设置。
#那么,我们该如何如何爬取我们想爬的这些网页的信息呢?
可以通过设置一些headers信息,模拟成浏览器去访问这些网站。此时,就能解决这个问题。
'''
#让爬虫模拟成浏览器访问网页的设置方法
'''
方法一:使用build_opener()修改报头
由于urlopen()不支持一些HTTP的高级功能,所以,我们如果要修改报头,可以使用
urllib2.build_opener()进行,要爬取无法爬取的网页,我们可以使用如下代码:
'''
import urllib2
url = "http://blog.csdn.net/weiwei_pig/article/details/51178226"
headers=("User-Agent","Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36")
opener=urllib2.build_opener()
opener.addheaders=[headers]
data=opener.open(url).read()
'''
上述代码中,首先,我们定义了一个变量url存储要爬取的网址,然后再定义一个变量headers存储对应的User-Agent信息,
定义的格式为(“User-Agent”,具体信息),具体信息我们刚才已经从浏览器中获取了,该信息获取一次即可,
以后在爬取其他网站的时候可以直接用,所以可以保存起来,不用每次都通过F12去找。

然后,我们需要使用urllib2.build_opener()创建自定义的opener对象并赋给变量opener,接下来,设置opener对象的addheaders,即设置对应的头信息,
设置格式为:“opener对象名.addheaders=[头信息]”,设置好头信息之后,我们就可以使用opener对象的open()方法打开对应的网址了。
此时,打开操作是已经具有头信息的打开操作行为,即会模仿为浏览器去打开,使用格式是“opener对象名.open(url地址)”。
打开对应网址后,再使用read()方法读取对应数据,并赋给data变量。
'''
#此时,我们成功实现了模拟浏览器去爬取对应的网页
#可以将对应的内容写入文件
fhandle=open("E://3.html","wb")
fhandle.write(data)
fhandle.close()
#若未发现报错,则爬取网页成功,同时可以看到有相关的3.html文档

'''
方法2:使用add_header()添加报头
'''
import urllib2
url ="http://blog.csdn.net/weiwei_pig/article/details/51178226"
req=urllib2.Request(url)
req.add_header("User-Agent","Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36")
data=urllib2.urlopen(req).read() #对应于python3的data=urlib.request.urlopen(req).read()
'''
首先,设置要爬取的网址,然后使用urllib2.Request(url)创建一个Request对象
并赋给变量req,创建对象的格式为:urllib2.Request(url地址)。

随后,使用add_header()方法添加对应的报头信息,格式为:Request对象名.add_header(字段名,字段值)

时,已经成功设置好报头,然后我们使用urlopen()打开该Request对象即可打开对应网址,所以此时我们使用
data=urllib2.urlopen(req).read()打开了对应网址并读取了网页内容,并赋给了data变量。

此时,成功模拟浏览器爬取了对应网址的信息。我们同样可以像方法1中一样将对应的信息写入文件。
'''
'''
以上两种方法都可以实现报头的添加,我们可以发现,这两种方法都是使用设置报头中的User-Agent字段信息来将对应的访问行为模仿成浏览器访问,避免了403错误。
只是添加报文的方法有所不同,值得注意的是,方法1中使用的是addheaders()方法,方法2中使用的是add_header()方法,注意末尾有无s以及有无下划线的区别。
'''