logo头像

一路过来,不过游牧自己。。

爬虫系列(二)


要学好爬虫,当然要先从最基本的开始学,学习她的“套路”,其实以后的东西,都和这个套路差不多,明白套路,实际上手练几个爬虫,多多少少可以应付一些网站的爬取!

首先入门应该从urllib开始学起,虽然到后面我们都不怎么去用,可能是效率偏低,但确是入门的好材料!

一、urllib的基本用法

1、用urllib去爬取一个网页

一般的网页上的信息要怎样抓取呢!本质就是根据URL去获取它的网页信息。我们我们在浏览器中看到的是一幅幅优美的画面,其实是由浏览器解释才呈现出来的,实质它是一段HTML代码,加 JS、CSS,如果把网页比作一个人,那么HTML便是他的骨架,JS便是他的肌肉,CSS便是它的衣服。所以最重要的部分是存在于HTML中的,下面我们就写个例子来扒一个网页下来。

1
2
3
import urllib2
response = urllib2.urlopen("http://www.baidu.com")
print response.read()

是的你没看错,真正的程序就两行,把它保存成 demo.py,进入该文件的目录,执行如下命令查看运行结果:

1
python demo.py

这里我们可以看到网页都被扒下来了,这里的pyhton版本是python2.7,3以上的教程也有了,可以去搜搜看。
baidujietu
看吧,这些输出的东西就是我们刚刚爬取下来的东西!

2、我们来分析分析

首先第一行:

1
response = urllib2.urlopen("http://www.baidu.com")

urlopen是urllib2库里面的方法,传入一个URL,这个网址是百度,首页协议是HTTP协议,当然你也可以把HTTP换做FTP,FILE,HTTPS 等等,只是代表了一种访问控制协议,urlopen一般接受三个参数,它的参数如下:

1
urlopen(url, data, timeout)

第一个参数url即为URL,第二个参数data是访问URL时要传送的数据,第三个timeout是设置超时时间。第二三个参数是可以不传送的,data默认为空None,timeout默认为 socket._GLOBAL_DEFAULT_TIMEOUT,第一个参数URL是必须要传送的,在这个例子里面我们传送了百度的URL,执行urlopen方法之后,返回一个response对象,返回信息便保存在这里面。

1
print response.read()

这时候我们就可以看到返回的就是这个网站的实体!这里注意一定要打read()哦,不然只会打出一串字符串!

3、用Request

1
2
3
4
5
import urllib2

request = urllib2.Request("http://www.baidu.com")
response = urllib2.urlopen(request)
print response.read()

这里我们可以用类似java的封装思想去弄,这样就逻辑比较清晰,推荐大家这么写,打出来的结果还是一样的

4、数据传送两种方式:POST和GET

以上的基本方式实现的是少数基本网页的抓取,不过现在大多数网站都是动态网页,需要你动态地传递参数给它,它做出对应的响应,例如是登录注册的时候!
数据传送分为POST和GET两种方式,两种方式有什么区别呢?
最重要的区别是GET方式是直接以链接形式访问,链接中包含了所有的参数,当然如果包含了密码的话是一种不安全的选择,不过你可以直观地看到自己提交了什么内容。POST则不会在网址上显示所有的参数,不过如果你想直接查看提交了什么就不太方便了。(例如有些网站用的get,那么你就可以看到你提交了一些什么样的参数)

(1)用post方法去实现网页登陆:

1
2
3
4
5
6
7
8
import urllib
import urllib2
values = {"username":"******@qq.com","password":"XXXX"}
data = urllib.urlencode(values)
url = "https://passport.csdn.net/account/login?from=http://my.csdn.net/my/mycsdn"
request = urllib2.Request(url,data)
response = urllib2.urlopen(request)
print response.read()

就是说在这传递的data 参数是username和password,不过记得要编码!这里是隐式的一个传送,是可以不再页面中显示出来的

(2)GET方式:

至于GET方式我们可以直接把参数写到网址上面,直接构建一个带参数的URL出来即可。

1
2
3
4
5
6
7
8
9
10
11
import urllib2

values={}
values['username'] = "1016903103@qq.com"
values['password']="XXXX"
data = urllib.urlencode(values)
url = "http://passport.csdn.net/account/login"
geturl = url + "?"+data
request = urllib2.Request(geturl)
response = urllib2.urlopen(request)
print response.read()

例如这样,他把这些数据加到了url后面,然后用?去分割!和我们平常GET访问方式一模一样,这样就实现了数据的GET方式传送

二、urllib的一些高级用法

1、设置Headers

如果程序直接用上面的方式进行访问,有些网站不会同意,如果识别有问题,那么站点根本不会响应,所以为了完全模拟浏览器的工作,我们需要设置一些Headers 的属性。
我们来看看知乎的例子吧:
知乎页面分析
右键检查,network,选中,就可以看到这些信息!这些内容也不是一次性就加载完成的,实质上是执行了好多次请求,一般是首先请求HTML文件,然后加载JS,CSS 等等,经过多次请求之后,网页的骨架和肌肉全了,整个网页的效果也就出来了。
我们看看这些请求,有个Request URL,还有headers,下面便是response,agent就是请求的身份,如果没有写入请求身份,那么服务器不一定会响应,所以可以在headers中设置agent,例如下面的例子,这个例子只是说明了怎样设置的headers,了解一下设置格式就好。

1
2
3
4
5
6
7
8
9
10
11
import urllib  
import urllib2

url = 'http://www.server.com/login'
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
values = {'username' : 'cqc', 'password' : 'XXXX' }
headers = { 'User-Agent' : user_agent }
data = urllib.urlencode(values)
request = urllib2.Request(url, data, headers)
response = urllib2.urlopen(request)
page = response.read()

这样,我们设置了一个headers,在headers中去设置agent,在构建request时传入,在请求时,就加入了headers传送,这样就会假装是浏览器去访问。
另外,我们还有对付”反盗链”的方式,对付防盗链,服务器会识别headers中的referer是不是它自己,如果不是,有的服务器不会响应,所以我们还可以在headers中加入referer,例如我们可以构建下面的headers

1
2
headers = { 'User-Agent' : 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'  ,
'Referer':'http://www.zhihu.com/articles' }

2、 Proxy(代理)的设置

假如一个网站它会检测某一段时间某个IP 的访问次数,如果访问次数过多,它会禁止你的访问。所以你可以设置一些代理服务器来帮助你做工作,每隔一段时间换一个代理,网站不知道是谁在访问,这样就会认为是正常访问!上上篇有篇博客就有讲这个ip代理问题!
面一段代码说明了代理的设置用法:

1
2
3
4
5
6
7
8
9
import urllib2
enable_proxy = True
proxy_handler = urllib2.ProxyHandler({"http" : 'http://some-proxy.com:8080'})
null_proxy_handler = urllib2.ProxyHandler({})
if enable_proxy:
opener = urllib2.build_opener(proxy_handler)
else:
opener = urllib2.build_opener(null_proxy_handler)
urllib2.install_opener(opener)

3、Timeout 设置

为了解决一些网站实在响应过慢而造成的影响。通过设置urlopen方法,第三个参数就是timeout的设置
例如:

1
2
import urllib2
response = urllib2.urlopen('http://www.baidu.com', timeout=10)

4、使用 HTTP 的 PUT 和 DELETE 方法

http协议有六种请求方法,get,head,put,delete,post,options,下面讲讲put和post区别
PUT:这个方法比较少见。HTML表单也不支持这个。本质上来讲, PUT和POST极为相似,都是向服务器发送数据,但它们之间有一个重要区别,PUT通常指定了资源的存放位置,而POST则没有,POST的数据存放位置由服务器自己决定。
DELETE:删除某一个资源。基本上这个也很少见,不过还是有一些地方比如amazon的S3云服务里面就用的这个方法来删除资源。

5.使用DebugLog

可以通过下面的方法把 Debug Log 打开,这样收发包的内容就会在屏幕上打印出来,方便调试!

1
2
3
4
5
6
import urllib2
httpHandler = urllib2.HTTPHandler(debuglevel=1)
httpsHandler = urllib2.HTTPSHandler(debuglevel=1)
opener = urllib2.build_opener(httpHandler, httpsHandler)
urllib2.install_opener(opener)
response = urllib2.urlopen('http://www.baidu.com')

基本就这么多了,下面还有cookie使用和正则,慢慢学习吧!

多走路,多思考,越努力,越幸运!
———————————————YoungerFary

微信打赏

赞赏是不耍流氓的鼓励