Python中urllib+urllib2+cookielib模块编写爬虫实战

超文本传输协议http构成了万维网的基础,它利用URI(统一资源标识符)来识别Internet上的数据,而指定文档地址的URI被称为URL(既统一资源定位符),常见的URL指向文件、目录或者执行复杂任务的对象(如数据库查找,internet搜索),而爬虫实质上正是通过对这些url进行访问、操作,从而获取我们想要的内容。对于没有商业需求的我们而言,想要编写爬虫的话,使用urllib,urllib2与cookielib三个模块便可以完成很多需求了。
首先要说明的是,urllib2并非是urllib的升级版,虽然同样作为处理url的相关模块,个人推荐尽量使用urllib2的接口,但我们并不能用urllib2完全代替urllib,处理URL资源有时会需要urllib中的一些函数(如urllib.urllencode)来处理数据。但二者处理url的大致思想都是通过底层封装好的接口让我们能够对url像对本地文件一样进行读取等操作。
下面就是一个获取百度页面内容的代码:

import urllib2
connect= urllib2.Request('http://www.baidu.com')
url1 = urllib2.urlopen(connect)
print url.read()

短短4行在运行之后,就会显示出百度页面的源代码。它的机理是什么呢?
当我们使用urllib2.Request的命令时,我们就向百度搜索的url(“www.baidu.com”)发出了一次HTTP请求,并将该请求映射到connect变量中,当我们使用urllib2.urlopen操作connect后,就会将connect的值返回到url1中,然后我们就可以像操作本地文件一样对url1进行操作,比如这里我们就使用了read()函数来读取该url的源代码。
这样,我们就可以写一只属于自己的简单爬虫了~下面是我写的抓取天涯连载的爬虫:

import urllib2
url1="http://bbs.tianya.cn/post-16-835537-"
url3=".shtml#ty_vip_look[%E6%8B%89%E9%A3%8E%E7%86%8A%E7%8C%AB"
for i in range(1,481):
  a=urllib2.Request(url1+str(i)+url3)
  b=urllib2.urlopen(a)
  path=str("D:/noval/天眼传人"+str(i)+".html")
  c=open(path,"w+")
  code=b.read()
  c.write(code)
  c.close
  print "当前下载页数:",i

事实上,上面的代码使用urlopen就可以达到相同的效果了:

import urllib2
url1="http://bbs.tianya.cn/post-16-835537-"
url3=".shtml#ty_vip_look[%E6%8B%89%E9%A3%8E%E7%86%8A%E7%8C%AB"
for i in range(1,481):
  #a=urllib2.Request(url1+str(i)+url3)
  b=urllib2.urlopen((url1+str(i)+url3)
  path=str("D:/noval/天眼传人"+str(i)+".html")
  c=open(path,"w+")
  code=b.read()
  c.write(code)
  c.close
  print "当前下载页数:",i

为什么我们还需要先对url进行request处理呢?这里需要引入opener的概念,当我们使用urllib处理url的时候,实际上是通过urllib2.OpenerDirector实例进行工作,他会自己调用资源进行各种操作如通过协议、打开url、处理cookie等。而urlopen方法使用的是默认的opener来处理问题,也就是说,相当的简单粗暴~对于我们post数据、设置header、设置代理等需求完全满足不了。
因此,当面对稍微高点的需求时,我们就需要通过urllib2.build_opener()来创建属于自己的opener,这部分内容我会在下篇博客中详细写~

而对于一些没有特别要求的网站,仅仅使用urllib的2个模块其实就可以获取到我们想要的信息了,但是一些需要模拟登陆或者需要权限的网站,就需要我们处理cookies后才能顺利抓取上面的信息,这时候就需要Cookielib模块了。cookielib 模块就是专门用来处理cookie相关了,其中比较常用的方法就是能够自动处理cookie的CookieJar()了,它可以自动存储HTTP请求生成的cookie,并向传出HTTP的请求中自动添加cookie。正如我前文所提到的,想要使用它的话,需要创建一个新的opener:

import cookielib, urllib2
cj = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))

经过这样的处理后,cookie的问题就解决了~
而想要将cookies输出出来的话,使用print cj._cookies.values()命令后就可以了~

抓取豆瓣同城、登陆图书馆查询图书归还
在掌握了urllib几个模块的相关用法后,接下来就是进入实战步骤了~

(一)抓取豆瓣网站同城活动

豆瓣北京同城活动  该链接指向豆瓣同城活动的列表,向该链接发起request:

# encoding=utf-8
import urllib
import urllib2
import cookielib
import re 

cj=cookielib.CookieJar()
opener=urllib2.build_opener(urllib2.HTTPCookieProcessor(cj)) 

url="http://beijing.douban.com/events/future-all?start=0"
req=urllib2.Request(url)
event=urllib2.urlopen(req)
str1=event.read()

我们会发现返回的html代码中,除了我们需要的信息之外,还夹杂了大量的页面布局代码:

如上图所示,我们只需要中间那些关于活动的信息。而为了提取信息,我们就需要正则表达式了~
正则表达式是一种跨平台的字符串处理工具/方法,通过正则表达式,我们可以比较轻松的提取字符串中我们想要的内容~
这里不做详细介绍了,个人推荐余晟老师的正则指引,挺适合新手入门的。下面给出正则表达式的大致语法:

这里我使用捕获分组,将活动四要素(名称,时间,地点,费用)为标准进行分组,得到的表达式如下:

代码如下:

regex=re.compile(r'summary">([\d\D]*?)</span>[\d\D]*?class="hidden-xs">([\d\D]*?)<time[\d\D]*?<li title="([\d\D]*?)">[\d\D]*?strong>([\d\D]*?)</strong>')

这样就可以将几个部分提取出来了。

总体代码如下:

# -*- coding: utf-8 -*-
#---------------------------------------
#  program:豆瓣同城爬虫
#  author:GisLu
#  data:2014-02-08
#--------------------------------------- 

import urllib
import urllib2
import cookielib
import re 

cj=cookielib.CookieJar()
opener=urllib2.build_opener(urllib2.HTTPCookieProcessor(cj)) 

#正则提取
def search(str1):
  regex=re.compile(r'summary">([\d\D]*?)</span>[\d\D]*?class="hidden-xs">([\d\D]*?)<time[\d\D]*?<li title="([\d\D]*?)">[\d\D]*?strong>([\d\D]*?)</strong>')
  for i in regex.finditer(str1):
    print "活动名称:",i.group(1)
    a=i.group(2)
    b=a.replace('</span>','')
    print b.replace('\n','')
    print '活动地点:',i.group(3)
    c=i.group(4).decode('utf-8')
    print '费用:',c 

#获取url
for i in range(0,5):
  url="http://beijing.douban.com/events/future-all?start="
  url=url+str(i*10)
  req=urllib2.Request(url)
  event=urllib2.urlopen(req)
  str1=event.read()
  search(str1)

在这里需要注意一下编码的问题,因为我使用的版本还是python2.X,所以在内部汉字字符串传递的时候需要来回转换,比如在最后打印“费用“这一项的时候,必须使用
i.group(4).decode('utf-8') 将group(4元组中的ASCII码转换为utf8格式才行,否则会发现输出的是乱码。
而在python中,正则模块re提供了两种常用的全局查找方式:findall 和 finditer,其中findall是一次性处理完毕,比较消耗资源;而finditer则是迭代进行搜索,个人比较推荐使用这一方法。

最后得到的结果如下,大功告成~

(二)模拟登陆图书馆系统查询书籍归还情况

既然我们能够通过python向指定网站发出请求获取信息,那么自然也能通过python模拟浏览器进行登陆等操作~
而模拟的关键,就在于我们向指定网站服务器发送的信息需要和浏览器的格式一模一样才行~
这就需要分析出我们想要登陆的那个网站接受信息的方式。通常我们需要对浏览器的信息交换进行抓包~
抓包软件中,目前比较流行的是wireshark,相当强大~不过对于我们新手来说,IE、Foxfire或者chrome自带的工具就足够我们使用了~

这里就以本人学校的图书馆系统为例子~

我们可以通过模拟登陆,最后进入图书管理系统查询我们借阅的图书归还情况。首先要进行抓包分析我们需要发送哪些信息才能成功模拟浏览器进行登陆操作。

我使用的是chrome浏览器,在登陆页面按F12调出chrome自带的开发工具,选择network项就可以输入学号密码选择登陆了。
观察登陆过程中的网络活动,果然发现可疑分子了:

分析这个post指令后,可以确认其就是发送登陆信息(账号、密码等)的关键命令。
还好我们学校比较穷,网站做的一般,这个包完全没有加密~那么剩下的就很简单了~记下headers跟post data就OK了~
其中headers中有很多实用的信息,一些网站可能会根据user-Agent来判断你是否是爬虫程序从而决定是否允许你访问,而Referer则是很多网站常常用来反盗链的,如果服务器接收到的请求中referer与管理员设定的规则不符,那么服务器也会拒绝发送资源。
而post data就是我们在登录过程中浏览器向登陆服务器post的信息了,通常账户、密码之类的数据都包含在里面。这里往往还有一些其他的数据如布局等信息也要发送出去,这些信息通常我们在操作浏览器的时候没有任何存在感,但没了他们服务器是不会响应我们滴。

现在postdata 跟headers的格式我们全部知道了~模拟登陆就很简单了:

import urllib
#---------------------------------------
#  @program:图书借阅查询
#  @author:GisLu
#  @data:2014-02-08
#--------------------------------------- 

import urllib2
import cookielib
import re 

cj=cookielib.CookieJar()
opener=urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
opener.addheaders = [('User-agent','Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)')] 

urllib2.install_opener(opener) 

#登陆获取cookies
postdata=urllib.urlencode({
    'user':'X1234564',
    'pw':'demacialalala',
    'imageField.x':'0',
    'imageField.y':'0'}) 

rep=urllib2.Request(
      url='http://210.45.210.6/dzjs/login.asp',
      data=postdata
    )
result=urllib2.urlopen(rep)
print result.geturl()

其中urllib.urlencode负责将postdata自动进行格式转换,而opener.addheaders则是在我们的opener处理器中为后续请求添加我们预设的headers。
测试后发现,登陆成功~~
那么剩下的就是找出图书借还查询所在页面的url,再用正则表达式提取出我们需要的信息了~~
整体代码如下:

import urllib
#---------------------------------------
#  @program:图书借阅查询
#  @author:GisLu
#  @data:2014-02-08
#--------------------------------------- 

import urllib2
import cookielib
import re 

cj=cookielib.CookieJar()
opener=urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
opener.addheaders = [('User-agent','Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)')] 

urllib2.install_opener(opener) 

#登陆获取cookies
postdata=urllib.urlencode({
    'user':'X11134564',
    'pw':'demacialalala',
    'imageField.x':'0',
    'imageField.y':'0'}) 

rep=urllib2.Request(
      url='http://210.45.210.6/dzjs/login.asp',
      data=postdata
    )
result=urllib2.urlopen(rep)
print result.geturl() 

#获取账目表 

Postdata=urllib.urlencode({
    'nCxfs':'1',
    'submit1':'检索'}) 

aa=urllib2.Request(
  url='http://210.45.210.6/dzjs/jhcx.asp',
  data=Postdata
  )
bb=urllib2.urlopen(aa)
cc=bb.read()
zhangmu=re.findall('tdborder4 >(.*?)</td>',cc) 

for i in zhangmu:
  i=i.decode('gb2312')
  i=i.encode('gb2312')
  print i.strip('  ')

下面是程序运行结果~

(0)

相关推荐

  • python使用cookielib库示例分享

    该模块主要功能是提供可存储cookie的对象.使用此模块捕获cookie并在后续连接请求时重新发送,还可以用来处理包含cookie数据的文件. 这个模块主要提供了这几个对象,CookieJar,FileCookieJar,MozillaCookieJar,LWPCookieJar. 1. CookieJar CookieJar对象存储在内存中. 复制代码 代码如下: >>> import urllib2>>> import cookielib>>> c

  • python cookielib 登录人人网的实现代码

    先上脚本吧,等下来讲下知识点: 复制代码 代码如下: #!/usr/bin/env python #encoding=utf-8 import sys import re import urllib2 import urllib import cookielib class Renren(object): def __init__(self): self.name = self.pwd = self.content = self.domain = self.origURL = '' self.o

  • Python使用cookielib模块操作cookie的实例教程

    cookielib是一个自动处理cookies的模块,如果我们在使用爬虫等技术的时候需要保存cookie,那么cookielib会让你事半功倍!他最常见的搭档模块就是python下的urllib和request. 核心类 1.Cookie 该类实现了Netscape and RFC 2965 cookies定义的cookie标准,基本可以理解为某一条cookie数据. 部分代码如下,很多属性是不是很眼熟? self.domain_initial_dot = domain_initial_dot

  • 在Python中使用cookielib和urllib2配合PyQuery抓取网页信息

    刚才好无聊,突然想起来之前做一个课表的点子,于是百度了起来. 刚开始,我是这样想的:在写微信墙的时候,用到了urllib2[两行代码抓网页],那么就只剩下解析html了.于是百度:python解析html.发现一篇好文章,其中介绍到了pyQuery. pyQuery 是 jQuery 在 Python 中的实现,能够以 jQuery 的语法來操作解析 HTML 文档.使用前需要安装,Mac安装方法如下: sudo easy_install pyquery OK!安装好了! 我们来试一试吧: fr

  • 使用Python中的cookielib模拟登录网站

    前面简单提到了 Python 模拟登录的程序,但是没写清楚,这里再补上一个带注释的 Python 模拟登录的示例程序.简单说一下流程:先用cookielib获取cookie,再用获取到的cookie,进入需要登录的网站. # -*- coding: utf-8 -*- # !/usr/bin/python import urllib2 import urllib import cookielib import re auth_url = 'http://www.nowamagic.net/' h

  • Python中urllib+urllib2+cookielib模块编写爬虫实战

    超文本传输协议http构成了万维网的基础,它利用URI(统一资源标识符)来识别Internet上的数据,而指定文档地址的URI被称为URL(既统一资源定位符),常见的URL指向文件.目录或者执行复杂任务的对象(如数据库查找,internet搜索),而爬虫实质上正是通过对这些url进行访问.操作,从而获取我们想要的内容.对于没有商业需求的我们而言,想要编写爬虫的话,使用urllib,urllib2与cookielib三个模块便可以完成很多需求了. 首先要说明的是,urllib2并非是urllib的

  • python中urllib模块用法实例详解

    本文实例讲述了python中urllib模块用法.分享给大家供大家参考.具体分析如下: 一.问题: 近期公司项目的需求是根据客户提供的api,我们定时去获取数据, 之前的方案是用php收集任务存入到redis队列,然后在linux下做一个常驻进程跑某一个php文件, 该php文件就一个无限循环,判断redis队列,有就执行,没有就break. 二.解决方法: 最近刚好学了一下python, python的urllib模块或许比php的curl更快,而且简单. 贴一下代码 复制代码 代码如下: #

  • 深入解析Python中的urllib2模块

    Python 标准库中有很多实用的工具类,但是在具体使用时,标准库文档上对使用细节描述的并不清楚,比如 urllib2 这个 HTTP 客户端库.这里总结了一些 urllib2 的使用细节. Proxy 的设置 Timeout 设置 在 HTTP Request 中加入特定的 Header Redirect Cookie 使用 HTTP 的 PUT 和 DELETE 方法 得到 HTTP 的返回码 Debug Log Proxy 的设置 urllib2 默认会使用环境变量 http_proxy

  • 对python中的six.moves模块的下载函数urlretrieve详解

    实验环境:windows 7,anaconda 3(python 3.5),tensorflow(gpu/cpu) 函数介绍:所用函数为six.moves下的urllib中的函数,调用如下urllib.request.urlretrieve(url,[filepath,[recall_func,[data]]]).简单介绍一下,url是必填的指的是下载地址,filepath指的是保存的本地地址,recall_func指的是回调函数,下载过程中会调用可以用来显示下载进度. 实验代码:以下载cifa

  • python中urllib.request和requests的使用及区别详解

    urllib.request 我们都知道,urlopen()方法能发起最基本对的请求发起,但仅仅这些在我们的实际应用中一般都是不够的,可能我们需要加入headers之类的参数,那需要用功能更为强大的Request类来构建了 在不需要任何其他参数配置的时候,可直接通过urlopen()方法来发起一个简单的web请求 发起一个简单的请求 import urllib.request url='https://www.douban.com' webPage=urllib.request.urlopen(

  • 浅谈python中常用的excel模块库

    openpyxl openpyxl是⼀个Python库,用于读取/写⼊Excel 2010 xlsx / xlsm / xltx / xltm⽂件. 它的诞⽣是因为缺少可从Python本地读取/写⼊Office Open XML格式的库. 如何安装: 使用pip安装openpyxl $ pip install openpyxl 使用效果之⼀: 比如可以直接读取表格数据后综合输出写⼊到后⾯的⼀列中 xlwings xlwings是BSD许可的Python库,可轻松从Excel调用Python,同样

  • Python中的pprint打印模块

    目录 1. 引言 2. 使用背景 3. pprint 大法好 4. 设定输出宽度 5. 设定输出缩进 6. 总结 1. 引言 ​​pprint​的英文全称​​Data pretty printer​​,顾名思义就是让显示结果更加直观漂亮. ​​print()​和​​pprint()​都是python的打印模块,功能基本一样,唯一的区别就是​​pprint()​模块打印出来的数据结构更加完整,每行为一个数据结构,更加方便阅读打印输出结果.特别是对于特别长的数据打印,​​print()​​输出结果都

  • Python中几种导入模块的方式总结

    模块内部封装了很多实用的功能,有时在模块外部调用就需要将其导入.常见的方式有如下几种: 1 . import >>> import sys >>> sys.path ['', 'C:\\Python34\\Lib\\idlelib', 'C:\\Windows\\system32\\python34.zip', 'C:\\Python34\\DLLs', 'C:\\Python34\\lib', 'C:\\Python34', 'C:\\Python34\\lib\\s

  • python中os和sys模块的区别与常用方法总结

    前言 本文主要介绍了关于python中os和sys模块区别与常用方法的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 官方解释: os: This module provides a portable way of using operating system dependent functionality. 翻译:提供一种方便的使用操作系统函数的方法. sys:This module provides access to some variables used or

  • 在Python中关于使用os模块遍历目录的实现方法

    一.Python中os模块的常见的使用方法 os.listdir(path):遍历path的文件或者文件夹,返回一个列表 os.path.join(path1,path2,--,pathn):拼接路径 os.path.isdir(path):判断此路径对应的是否是文件夹 os.path.isfile(path):判断是否是文件 os.path.dirname(path):返回路径的文件夹名 os.path.filename(path):返回路径的文件名 os.getcwd():获取当前路径 二.

随机推荐