爬了个爬(补充)关于重定向

  重定向,一直是爬取数据时头疼的一个问题!首先明确,重定向是浏览器做了两次resquest请求!!!出现重定向基本上有两种方式:后台redirect,或是前端访问时的location。

  每个网站主页是网站资源的入口,当重定向发生在网站主页时,如果不能正确处理就很有可能会错失这整个网站的内容。

1、服务器端重定向,在服务器端完成,一般来说爬虫可以自适应,是不需要特别处理的,如响应代码301(永久重定向)、302(暂时重定向)等。具体来说,可以通过requests请求得到的response对象中的url、status_code两个属性来判断。当status_code为301、302或其他代表重定向的代码时,表示原请求被重定向;当response对象的url属性与发送请求时的链接不一致时,也说明了原请求被重定向且已经自动处理。

  举例:Django后台,给前端页面返回 redirect() 【新的url】可以实现跳转到其他页面,内部原理是让浏览器重定向,重新再根据这个新的url,向这个url对应的服务器发送访问请求!;前端更简单:直接给定url地址,状态码;直接跳转!

重定向简单举例:通过socket实现跳转

# !/usr/bin/env python
# coding:utf-8

import socket


def handle_request(client):
    buf = client.recv(1024)
    client.send(b"HTTP/1.1 302 OK\r\nlocation:http://www.baidu.com\r\n\r\n") #访问当前页面,然后跳转到百度
    client.send(b"Hello, Seven")


def main():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind(('localhost', 8000))
    sock.listen(5)

    while True:
        connection, address = sock.accept()
        handle_request(connection)
        connection.close()


if __name__ == '__main__':
    main()

  2、meta refresh,即网页中的<meta>标签声明了网页重定向的链接,这种重定向由浏览器完成,需要编写代码进行处理。例如,某一重定向如下面的html代码第三行中的注释所示,浏览器能够自动跳转,但爬虫只能得到跳转前的页面,不能自动跳转。

<html>  
	<head>  
		<meta http-equiv="refresh" content="0.1;url=http://www.baidu.com/"><!--本网页会在0.1秒内refresh为url所指的网页-->  
	</head>  
</html> 

  解决办法是通过得到跳转前的页面源码,从中提取出重定向url信息(上述代码第三行中的url属性值)。
    一个具体的操作:①使用xpath('//meta[@http-equiv="refresh" and @content]/@content')提取出content的值 ②使用正则表达式提取出重定向的url值。

3、js 重定向,通过JavaScript代码形式进行重定向。如下面JavaScript代码

<script language=javascript>window.location.href='http://www.baidu.com'</script>

  对于这种方式的跳转,由于可以实现该功能的JavaScript语句有多种形式,不能再使用正则表达式提取url,只能考虑加载JavaScript代码来进行解决。

  

  重定向收到后,查看返回的302时,解析返回的内容,获取到重定向以后的URL。然后爬虫访问新的URL。如果我们是通过requests模块发起请求的话,可以通过在请求中添加 allow_redirects=False 拒绝默认的301/302重定向,通过response.headers[‘Location’]从而拿到Location(重定向页面URL)。

def yunsite():
	"""
	爬虫重定向举例
	"""
	headers = {
		'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
		'Accept-Encoding': 'gzip, deflate, sdch, br',
		'Accept-Language': 'zh-CN,zh;q=0.8',
		'Cache-Control':'max-age=0',
		'Connection': 'keep-alive',
		'Host': 'pan.baidu.com',
		'Referer':'https://pan.baidu.com/',
		'Upgrade-Insecure-Requests': '1',
		'User-Agent': Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.104 Safari/537.36 Core/1.53.3373.400 QQBrowser/9.6.11866.400}   
	url = 'https://pan.baidu.com/s/1c0rjnbi'
	
	html = requests.get(url, headers=headers, allow_redirects=False)
	new_url = html.headers['Location'] #重定向的url
	code = html.status_code    #状态码
	return (new_url,code)

response.status_code 打印请求返回的状态码

 

posted @ 2017-09-06 09:20  细雨蓝枫  阅读(1117)  评论(0)    收藏  举报