首页 后端开发 Python教程 Python中urllib+urllib2+cookielib模块编写爬虫实战

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

Jun 10, 2016 pm 03:06 PM
python urllib 爬虫

超文本传输协议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代码中,除了我们需要的信息之外,还夹杂了大量的页面布局代码:

2016120143529274.jpg (659×571)

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

2016120143546024.jpg (799×1719)

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

复制代码 代码如下:


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

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

总体代码如下:

# -*- 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]*&#63;)</span>[\d\D]*&#63;class="hidden-xs">([\d\D]*&#63;)<time[\d\D]*&#63;<li title="([\d\D]*&#63;)">[\d\D]*&#63;strong>([\d\D]*&#63;)</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&#63;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则是迭代进行搜索,个人比较推荐使用这一方法。

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

2016120143648197.jpg (595×488)

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

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

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

2016120143733259.jpg (613×276)

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

2016120143755049.jpg (958×609)

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

2016120143815420.jpg (840×83)

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

2016120143835688.jpg (667×261)

2016120143856192.jpg (287×165)

现在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 >(.*&#63;)</td>',cc) 
 
for i in zhangmu: 
  i=i.decode('gb2312') 
  i=i.encode('gb2312') 
  print i.strip('  ') 
登录后复制

下面是程序运行结果~

2016120143937841.jpg (254×300)

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1662
14
CakePHP 教程
1419
52
Laravel 教程
1313
25
PHP教程
1262
29
C# 教程
1235
24
PHP和Python:解释了不同的范例 PHP和Python:解释了不同的范例 Apr 18, 2025 am 12:26 AM

PHP主要是过程式编程,但也支持面向对象编程(OOP);Python支持多种范式,包括OOP、函数式和过程式编程。PHP适合web开发,Python适用于多种应用,如数据分析和机器学习。

在PHP和Python之间进行选择:指南 在PHP和Python之间进行选择:指南 Apr 18, 2025 am 12:24 AM

PHP适合网页开发和快速原型开发,Python适用于数据科学和机器学习。1.PHP用于动态网页开发,语法简单,适合快速开发。2.Python语法简洁,适用于多领域,库生态系统强大。

PHP和Python:深入了解他们的历史 PHP和Python:深入了解他们的历史 Apr 18, 2025 am 12:25 AM

PHP起源于1994年,由RasmusLerdorf开发,最初用于跟踪网站访问者,逐渐演变为服务器端脚本语言,广泛应用于网页开发。Python由GuidovanRossum于1980年代末开发,1991年首次发布,强调代码可读性和简洁性,适用于科学计算、数据分析等领域。

Python vs. JavaScript:学习曲线和易用性 Python vs. JavaScript:学习曲线和易用性 Apr 16, 2025 am 12:12 AM

Python更适合初学者,学习曲线平缓,语法简洁;JavaScript适合前端开发,学习曲线较陡,语法灵活。1.Python语法直观,适用于数据科学和后端开发。2.JavaScript灵活,广泛用于前端和服务器端编程。

sublime怎么运行代码python sublime怎么运行代码python Apr 16, 2025 am 08:48 AM

在 Sublime Text 中运行 Python 代码,需先安装 Python 插件,再创建 .py 文件并编写代码,最后按 Ctrl B 运行代码,输出会在控制台中显示。

vscode在哪写代码 vscode在哪写代码 Apr 15, 2025 pm 09:54 PM

在 Visual Studio Code(VSCode)中编写代码简单易行,只需安装 VSCode、创建项目、选择语言、创建文件、编写代码、保存并运行即可。VSCode 的优点包括跨平台、免费开源、强大功能、扩展丰富,以及轻量快速。

visual studio code 可以用于 python 吗 visual studio code 可以用于 python 吗 Apr 15, 2025 pm 08:18 PM

VS Code 可用于编写 Python,并提供许多功能,使其成为开发 Python 应用程序的理想工具。它允许用户:安装 Python 扩展,以获得代码补全、语法高亮和调试等功能。使用调试器逐步跟踪代码,查找和修复错误。集成 Git,进行版本控制。使用代码格式化工具,保持代码一致性。使用 Linting 工具,提前发现潜在问题。

notepad 怎么运行python notepad 怎么运行python Apr 16, 2025 pm 07:33 PM

在 Notepad 中运行 Python 代码需要安装 Python 可执行文件和 NppExec 插件。安装 Python 并为其添加 PATH 后,在 NppExec 插件中配置命令为“python”、参数为“{CURRENT_DIRECTORY}{FILE_NAME}”,即可在 Notepad 中通过快捷键“F6”运行 Python 代码。

See all articles