用python爬数据

Python 爬虫

python版本2.7,操作系统ubuntu12.04,我是在eclipse实验的。下面是爬互联网网页数据的一些经验。

爬取网页数据核心就是解析网页源文件,思路就是先把网页所有源代码缓存到本地,然后通过软件包或者自己使用正则表达式提取想要找的东西。核心包就是urllib2,主要工具是re(正则表达式)+各种解析网页源代码的python包(beautifulsoup4 ),并行工具使用gevent.monkey包。更主要的工具是google+baidu,大概无论想要实现什么都会找到了。


闲话不多说,以爬 http://military.people.com.cn/n/2013/0705/c1011-22087628.html 为例:

<!-- lang: python -->
import urllib2
f=urllib2.urlopen('http://military.people.com.cn/n/2013/0705/c1011-22087628.html')
print f.read().lower()

urllib2包里面的urlopen方法打开了一个网址,返回一个socket类型,然后用.read()方法就可以读出url里面的文本,变成一个字符串类型,.lower()方法把所有英文字母变成小写,方便处理。

print之后,应该可以看到控制台输出了网页的源代码,不过会出现乱码。引出先面的编码问题: 看上面这个网页的源代码的头部文件 网页源代码

可以看到编码是GB2312,常用的还有GBK GB18030 这些好像是亚洲地区语言的编码,详细了解自己百度吧,反正都不一样。windows下的简体中文是GBK编码的,这三个之间貌似可以兼容,不过有区别。 同时,有的网页编码是UTF8 比如 http://www.douban.com/note/285271214/ (PS.貌似豆瓣整个就是python写的)。linux中的汉字的UTF-8编码的。 下面说一下汉字在内存中的表示 GBK类的编码中 一个汉字是这么表示的 /A1/8D/HA 这种东西 utf8 是 /u8fe1 这种东西

下面我们来解决编码问题,这也是我认为爬取中文网页的最麻烦的步骤。 首先,需要在源代码的第一行加入

<!-- lang: python -->
# -*- coding: utf-8 -*-

这一行,来保证你的程序可以认识中文,否则,像 print “你好” 这类的语句无法编译通过。 其次,由于屏幕输出和写入文件的原理不同,我有一次就是在控制台可以得到正确结果,但是输出到文件就有问题,所以需要在文件头部加入下面三句话

<!-- lang: python -->
import sys
reload(sys)
sys.setdefaultencoding('utf8')

汉字就是以字母和数字形式存在字符串中,用字符串的 .decode() 函数就可以实现解码,.encode()函数实现编码 重新输出 <!-- lang: python --> print f.read().lower().decode('gbk')

即可得到正确的汉字,同理,UTF-8编码的就 .decode('utf8')即可

如果我们爬的不是同一个网站下的网页,网址列表中有UTF8编码的,也有GBK编码的怎么办?使用try函数 try:
print s.decode('utf8')
except:
print s.decode('gb2312')

try和except 与 if else 的区别是,try不成功不会报错跳出,会转向执行except,而if else没有这个功能

现在网页的全部信息我们已经得到,下面的任务就是提取一些东西。 比较简单的,提取全部中文

<!-- lang: python -->
s=f.read().lower().decode('gbk')
zs=''
for item in s:
    if item in r'''0123456789{}%abcdefghijklmnopqrstuvwxyz'<>()?$+:&;|#!/"=-_.''':
        continue
    zs+=item
print zs  

三个单引号中的字符串表示要去掉的东西。不过有很多行,乱七八糟的。 当然这是非常粗暴的方法。

利器就是正则表达式,http://www.jb51.net/tools/zhengze.html 这是非茶馆你有名的一篇教程。python中用re包,正则表达式非常厉害,功能也很多,我只举一个简单的例子 在头部加入import re

<!-- lang: python -->
p=re.compile("\s+")
ns=re.sub(p,'',s)
print ns

这段话执行的是去掉所有空白字符 \t \n等 在这段话的基础上找所有汉字就是都连一起的了。 re.compile 是漏斗,起过滤的功能 <!-- lang: python --> ptitle="<title>.*?</title>" title=re.search(ptitle,ns) try: print title.group().decode("gb2312").strip("</title>") except: try: print title.group().decode("utf-8").strip("</title>") except: print ' None'

ptitle就是正则表达式, re.search是查询 这段话执行的结果是找到源文件中title标签中的内容。同理也可以找到其他标签中的内容。正则表达式的具体写法请参看上面的链接。

正则表达式的功能十分强大,可以提取出来任何你想要的东西,但是缺点就是太麻烦了。 我们使用beautifulsoup包来代替自己手写的正则表达式的操作。

在头部加入 <!-- lang: python --> from bs4 import BeautifulSoup 导入 beautifulsoup包 下面是一个完整的程序

<!-- lang: python -->
# -*- coding: utf-8 -*-
import urllib2
import sys,re
from bs4 import BeautifulSoup
reload(sys)
sys.setdefaultencoding('utf8')
f=urllib2.urlopen('http://military.people.com.cn/n/2013/0705/c1011-22087628.html')
s=f.read().lower().decode('gbk')    
soup = BeautifulSoup(s)
print soup.title
newstext=soup.find(id="p_content")
ss=''
for item in str(newstext):
    if item in r'''0123456789{}%abcdefghijklmnopqrstuvwxyz'<>()?$+:&;|#!/"=-_.''':
        continue
    ss+=item
print ss

beautifulsoup返回的是一个soup类型, 输出soup.title 即可提取出title标签,同理,也可以输出soup.description soup.keywords 详情参见beautiful的官方网站 soup.find(id="p_content")是按照标签id查找。

beautifulsoup的功能也非常强大,绝不是一篇博客能讲完的。

mechanize 是一个python模拟浏览器操作的包

下面一个程序通过使用mechanize包来完成在豆瓣电影搜索电影名字,抓取电影类型,演员,导演之类的任务。

<!-- lang: python -->
# -*- coding: utf-8 -*-
import sys,string,types
import mechanize
#sys.stdout=open('look','w')
file= open('list',"rb");
for name in file:
    br = mechanize.Browser()		#br是模拟的浏览器
    br.open('http://movie.douban.com/') #打开豆瓣电影页面
    br.select_form(nr=0)		#选一个表
    br.form['search_text']=name.decode('utf-8') #输入要查询的电影的名字
    br.submit()				#提交
    result = br.response()		#返回结果
    linkss = [l for l in  br.links()] #把浏览器链接加入linkss列表中
    rr = br.follow_link(linkss[21])   #点击搜索结果的第一条  这个21是尝试出来的,因为上面还有注册等等链接
    #print rr.read()
    ttt='<span class="pl">类型:</span> '  #手动找标签,也可以返回的源文件,用beautifulsoup解析
    #print br.title()
    ss=rr.read().split('\n')
    for line in ss:
        if line.find(ttt)>0:
            print line
    br.close()

输出的结果需要进一步处理,这里就不赘述了。 上面写的都只是普通网页的文本爬取,爬新浪微博之类的需要API,或者有其他的黑科技,那些都是等待钻研的东西了。

另外提供两个参考链接

http://www.pythonclub.org/python-network-application/observer-spider 是一篇写的挺详细的博客

http://www.oschina.net/project/tag/64/spider?lang=25 是oschina上的一个框架(不过我觉得都太高端了,供以进一步的参考)

转载于:https://my.oschina.net/chenyublog/blog/142895

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值