zoukankan      html  css  js  c++  java
  • 自学Python四 爬虫基础知识储备

      首先,推荐两个关于python爬虫不错的博客:Python爬虫入门教程专栏   和 Python爬虫学习系列教程 。写的都非常不错,我学习到了很多东西!在此,我就我看到的学到的进行总结一下!

      爬虫就是一个不断的去抓去网页的程序,根据我们的需要得到我们想要的结果!但我们又要让服务器感觉是我们人在通过浏览器浏览不是程序所为!归根到底就是我们通过程序访问网站得到html代码,然后分析html代码获取有效内容的过程。下面让我们从最简单的爬虫开始:

      爬取一个页面源代码

      在python中,抓取网页的库是urllib2。下面看一个最简单的例子:

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

      执行完成后你会发现窗口中打出了一堆代码,其实就是百度主页的html代码!(抵制百度!!!)

      我们来看一下urlopen的用法:

    1 >>> help(urllib2.urlopen)
    2 Help on function urlopen in module urllib2:
    3 
    4 urlopen(url, data=None, timeout=<object object>, cafile=None, capath=None, cadefault=False, context=None)

      第一个参数为url,第二个为要发送的数据,第三个是超时时间。其余的我们一般不用,就不解释了!第二三个参数不是必须的,因为都有默认值,data默认值为None,timeout默认值为socket._GLOBAL_DEFAUTL_TIMEOUT。传入url之后,我们得到一个response对象,返回的信息就在这里面!通过response.read()获取里面的内容。同样的我们可以构造一个Request类,作为参数传入urlopen中,这个Request类中就包含url,data,timeout等内容。上面的代码我们可以写成这样:

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

      这样是不是很清晰明了了?在构建Request的时候我们通常会加入很多内容,我们发出一个请求,服务器给我们一个响应。一个简单的爬虫就这样起飞了!

      POST和GET数据传送

      平常我们在浏览网页的时候难免涉及到登录注册,填写表单,或者跳转到某个页面,这时候我们要跟服务器进行交互,向服务器发送数据,发送数据的方式呢就是Post和Get,两者的区别在于GET方式直接以链接的形式访问,链接中包含所有的参数,如:http://www.baidu.com/shit?result=true  其中 result=true就是Get传递的数据,POST相当于Get就安全多了,它不会在链接上显示所有参数。

      Post方式:

     1 import urllib
     2 import urllib2
     3 
     4 values = {}
     5 values['username'] = "977610289@qq.com"
     6 values['password'] = "******"
     7 data = urllib.urlencode(values) 
     8 url = "http://www.xxx.com/login?from=http://xxx/loginInfo"
     9 request = urllib2.Request(url,data)
    10 response = urllib2.urlopen(request)
    11 print response.read()

      在上面的代码中,我们创建了一个字典values,设置了username和password的值,然后通过urlencode函数将字典进行转码,命名为data,然后用url和data实例化了一个Request类,传递给urlopen()。

      Get方式:

     1 import urllib
     2 import urllib2
     3 
     4 values={}
     5 values['username'] = "977610289@qq.com"
     6 values['password']="******"
     7 data = urllib.urlencode(values) 
     8 url = "http://www.xxx.com/login"
     9 geturl = url + "?"+data
    10 request = urllib2.Request(geturl)
    11 response = urllib2.urlopen(request)
    12 print response.read()

      在上面的代码中,我们创建了一个字典values,设置了username和password的值,然后通过urlencode函数将字典进行转码,命名为data,然后我们把data拼接在了url中,我们会得到这样的url:http://www.xxx.com/login?username=977610289%40qq.com&password=******。

      在实现一个爬虫的时候,我们要根据需要,选择post或者get方式进行访问!不过除了上面那些还不够,现在网站为了避免爬虫去访问会进行一些检测,如果检测不通过就不会响应你的请求,为了完全模拟浏览器工作,我们往往要设置一些headers属性,以及防盗链:

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

    3 request = urllib2.Request(url, data, headers)#利用data headers构造Request对象

      有些网站可能会检测ip等,我们可能会用到urllib2的代理,有些网站响应过慢我们可以设置其timeout。在访问网站的情况下我们可能会遇到一些网站错误,我们要在程序中进行处理(一如既往的try... except...得到错误信息内容):

     1 import urllib2
     2 
     3 req = urllib2.Request('http://www.xxx.com')
     4 try:
     5     urllib2.urlopen(req)
     6 except urllib2.URLError, e:
     7     if hasattr(e,"code"):
     8         print e.code
     9     if hasattr(e,"reason"):
    10         print e.reason
    11 else:
    12     print "OK"

      常见的错误代码:400 非法请求  403 禁止访问  404 未找到资源  500 服务器内部错误 200 访问成功。

      在网页访问过程中,不可避免的要用到cookies,我们的程序要模拟浏览器的行为,在访问网页的时候有时候要带上特定的cookies,这样才能成功访问网页。关于cookies我们用到了cookielib,cookielib模块提供可存储cookie的对象,以便于与urllib2配合使用进行网站访问,利用其中的CookieJar类捕获和发送cookie,实现模拟登录,维持登录状态等。

      获取cookie保存到变量:

     1 import urllib2
     2 import cookielib
     3 #声明一个CookieJar对象实例来保存cookie
     4 cookie = cookielib.CookieJar()
     5 #利用urllib2库的HTTPCookieProcessor对象来创建cookie处理器
     6 handler=urllib2.HTTPCookieProcessor(cookie)
     7 #通过handler来构建opener
     8 opener = urllib2.build_opener(handler)
     9 #此处的open方法同urllib2的urlopen方法,也可以传入request
    10 response = opener.open('http://www.baidu.com')
    11 for item in cookie:
    12     print 'Name = '+item.name
    13     print 'Value = '+item.value
    14 #利用cookie请求访问另一个网址
    15 gradeUrl = 'http://www.baidu.com/xxx/xx'
    16 #请求访问
    17 result = opener.open(gradeUrl)
    18 print result.read()

      上面程序创建了一个带有cookie的opener,在访问登录url的时候,将登录后的cookie保存下来,然后利用这个cookie来访问其他的网址。

      下面放一个HttpClient.py,里面包含了post和get方法,以及getcookies:

     1 import cookielib, urllib, urllib2, socket
     2 
     3 class HttpClient:
     4   __cookie = cookielib.CookieJar()
     5   __req = urllib2.build_opener(urllib2.HTTPCookieProcessor(__cookie))
     6   __req.addheaders = [
     7     ('Accept', 'application/javascript, */*;q=0.8'),
     8     ('User-Agent', 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)')
     9   ]
    10   urllib2.install_opener(__req)
    11 
    12   def Get(self, url, refer=None):
    13     try:
    14       req = urllib2.Request(url)
    15       if not (refer is None):
    16         req.add_header('Referer', refer)
    17       return urllib2.urlopen(req, timeout=120).read()
    18     except urllib2.HTTPError, e:
    19       return e.read()
    20     except socket.timeout, e:
    21       return ''
    22     except socket.error, e:
    23       return ''
    24 
    25   def Post(self, url, data, refer=None):
    26     try:
    27       req = urllib2.Request(url, urllib.urlencode(data))
    28       if not (refer is None):
    29         req.add_header('Referer', refer)
    30       return urllib2.urlopen(req, timeout=120).read()
    31     except urllib2.HTTPError, e:
    32       return e.read()
    33     except socket.timeout, e:
    34       return ''
    35     except socket.error, e:
    36       return ''
    37 
    38   def Download(self, url, file):
    39     output = open(file, 'wb')
    40     output.write(urllib2.urlopen(url).read())
    41     output.close()
    42 
    43   def getCookie(self, key):
    44     for c in self.__cookie:
    45       if c.name == key:
    46         return c.value
    47     return ''
    48 
    49   def setCookie(self, key, val, domain):
    50     ck = cookielib.Cookie(version=0, name=key, value=val, port=None, port_specified=False, domain=domain, domain_specified=False, domain_initial_dot=False, path='/', path_specified=True, secure=False, expires=None, discard=True, comment=None, comment_url=None, rest={'HttpOnly': None}, rfc2109=False)
    51     self.__cookie.set_cookie(ck)

      

  • 相关阅读:
    并发编程之守护进程、互斥锁以及队列等相关内容-37
    并发编程之进程理论及应用等相关内容-36
    补充知识之猴子补丁、内置函数以及垃圾回收机制等相关内容-35
    面向对象之元类等相关内容-34
    网络编程(套接字)之UDP协议通信以及基于socketserver模块实现并发效果等相关内容-33
    面向对象之组合、多态、以及内置函数及方法等相关内容-27
    面向对象之异常处理等相关内容-28
    网络基础之osi五层协议等相关内容-29
    网络编程(套接字)之TCP协议通信、远程执行命令等相关内容-31
    看到你很好,就行了,走啦!
  • 原文地址:https://www.cnblogs.com/jixin/p/5131040.html
Copyright © 2011-2022 走看看