python代码解析
最近准备好好学学python爬虫,从网上找了个例子,爬取豆瓣读书的信息,原文地址:http://blog.csdn.net/lanbing510/article/details/45887075
代码地址:
https://raw.githubusercontent.com/lanbing510/DouBanSpider/master/doubanSpider.py
因为以前基本没接触过python,所以对代码做个简单的解析,先贴下代码如下:
#-*- coding: UTF-8 -*-import sys
import time
import urllib
import urllib2
import requests
import numpy as np
from bs4 import BeautifulSoup
from openpyxl import Workbookreload(sys)
sys.setdefaultencoding('utf8')def book_spider(book_tag):page_num=0;count=1book_list=[]try_times=0#Some User Agentshds=[{'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'},\{'User-Agent':'Mozilla/5.0 (Windows NT 6.2) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.12 Safari/535.11'},\{'User-Agent': 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)'}]while(1):url="http://www.douban.com/tag/"+urllib.quote(book_tag)+"/book?start="+str(page_num*15)time.sleep(np.random.rand()*2)#Last Versiontry:req = urllib2.Request(url, headers=hds[page_num%len(hds)])source_code = urllib2.urlopen(req).read()plain_text=str(source_code) except (urllib2.HTTPError, urllib2.URLError), e:print econtinue##Previous Version, IP is easy to be Forbidden#source_code = requests.get(url) #plain_text = source_code.text soup = BeautifulSoup(plain_text)list_soup = soup.find('div', {'class': 'mod book-list'})try_times+=1;if list_soup==None and try_times<200:continueelif list_soup==None or len(list_soup)<=1:break # Break when no informatoin got after 200 times requestingfor book_info in list_soup.findAll('dd'):title = book_info.find('a', {'class':'title'}).string.strip()desc = book_info.find('div', {'class':'desc'}).string.strip()desc_list = desc.split('/')try:author_info = '作者/译者: ' + '/'.join(desc_list[0:-3])except:author_info='作者/译者: 暂无'try:pub_info = '出版信息: ' + '/'.join(desc_list[-3:])except:pub_info='出版信息: 暂无'try:rating = book_info.find('span', {'class':'rating_nums'}).string.strip()except:rating='0.0'try:people_num = book_info.findAll('span')[2].string.strip()people_num=people_num.strip('人评价')except:people_num='0'book_list.append([title,rating,people_num,author_info,pub_info])try_times=0 #set 0 when got valid informationpage_num+=1print "Downloading Information From Page %d" % page_numreturn book_listdef do_spider(book_tag_lists):book_lists=[]for book_tag in book_tag_lists:book_list=book_spider(book_tag)book_list=sorted(book_list,key=lambda x:x[1],reverse=True)book_lists.append(book_list)return book_listsdef print_book_lists_excel(book_lists,book_tag_lists):wb=Workbook(optimized_write=True)ws=[]for i in range(len(book_tag_lists)):ws.append(wb.create_sheet(title=book_tag_lists[i].decode())) #utf8->unicodefor i in range(len(book_tag_lists)): ws[i].append(['序号','书名','评分','评价人数','作者','出版社'])count=1for bl in book_lists[i]:ws[i].append([count,bl[0],float(bl[1]),int(bl[2]),bl[3],bl[4]])count+=1save_path='book_list'for i in range(len(book_tag_lists)):save_path+=('-'+book_tag_lists[i].decode())save_path+='.xlsx'wb.save(save_path)if __name__=='__main__':#book_tag_lists = ['心理','判断与决策','算法','数据结构','经济','历史']#book_tag_lists = ['传记','哲学','编程','创业','理财','社会学','佛教']#book_tag_lists=['思想','科技','科学','web','股票','爱情','两性']book_tag_lists=['计算机','机器学习','linux','android','数据库','互联网']book_lists=do_spider(book_tag_lists)print_book_lists_excel(book_lists,book_tag_lists)
代码解析:
1、import
引入其他模块的代码,有两种引入的方式 一种是import xxx,另外一种是from xxx import yyy,第一种针对单个的文件,第二种针对包,第二种意思是从yyy包里引入xxx,python引入的模块有多种形式,可以是python脚本、dll文件等等,具体见: python import
2、reload()
当需要重新载入某个模块的时候,可以使用reload载入某个模块,如reload(sys)意思就是重新载入某个模块,意思是将之前导入的模块再加载一次,这样允许在不退出解释器的情况下重新加载已经更改的模块,不过一般不建议这样做。
2、def
def定义一个模块的变量或者类的变量,它本身是一个函数对象。如def aaa(): 就定义了一个叫做aaa()的函数
3、变量定义
count=1 这句话就定义了一个叫count的变量,并将其赋值为1,非常直观。
4、数组
python的数组分为三种类型:
list 普通的链表,初始化后可通过特定的方法动态增加元素
定义方式 arr=[元素]
Tuple固定的数据,一旦定义后不可改变:
定义方式:arr=(元素)
Dictionary类型的数组,即Hash数组,
定义方式 arr={k:v}
5、循环
python支持常用的所有循环,包括while,for等,
如while(1):代表无限循环,除非内部跳出,for循环为foreash形式,形如
for ele in elements:循环遍历elements里的所有元素
6、time模块
time模块为python内建模块,比如我们可以用time.sleep(seconds)让程序休眠一段时间
7、异常处理
python中的异常处理格式为:
try:
语句1
语句2
。。。
except a,b:
处理异常语句...
finally:
清理工作...
其中的a和b分别是异常类型和异常对象,值得注意的是这里的异常类型可以是多个,如下:
except (urllib2.HTTPError, urllib2.URLError), e:
8、str()
将一个python的对象转化为对象,注意还有一个函数repr()也是这个功能,不过是它在转化为字符串之后还能转化为之前的对象
9、格式化输出
print "Downloading Information From Page %d" % page_num
看起来是不是很熟悉 ,很类似c语言的风格,其实也很好理解,实用最多的还是c实现的python,当然和C会有一些借鉴
10、strip(xxx)
删除一个字符串首位的xxx字符,如果什么都不传就是删除首位的空格
11、sorted()
排序
11、open()
打开文件,open(name[,mode[,buffering]])
其中name表示需要打开的文件名字,mode是打开模式,第三个参数用来控制是否缓冲,默认是0表示不缓冲,1表示缓冲。
其中mode才是open()的灵魂,
- 参数 描述
- r 读取模式打开文件
- w 读写模式打开文件
- a 写入模式打开文件
- b 二进制模式打开文件(可以和其他模式并用)
- + 读/写模式(可以和其他模式并用)
- U 支持换行符(例如:\n、\r 或 \n\r 等)
我们在使用open函数时,首先会函数的文件名称然后才是模式,文件模式是一个相当重要的参数,默认模式参数为'r',用只读的方式打开文件,如读取特殊文件如视频或者图片文件,必须使用'b'模式。
- o=open('index.txt','w');
- o.write("大家好,欢迎光临坤子的博客(www.xuyukun.com)!")
- o.close();
上面的代表表示将字符串写入到index.txt文件中
12、__main__ __init__
在c/c++/java中main是程序执行 的起点,python中也有类似的运行机制,不过方式有所不同,python使用缩进对齐组织代码的执行,所有没有缩进的代码(非函数定义和类定义)都会在载入时自动执行,这些代码可以认为是python的main函数。
python引入__main__变量是为了区分主执行文件还是被调用的文件,当文件是被调用时,__name__的值是模块名字,当文件被直接执行时,__name__的值是__main__,这个特性为测试驱动的开发提供了极好的支持,我们可以在每个模块中写上测试代码,这些测试代码只有在python文件被直接执行的时候才会运行,代码和测试完美的结合在一起。
13、#!/usr/bin/env python 和 #!/usr/bin/python
首先这两行的作用都是为了在运行python文件的时候不需要用python xxx.py这种方式而是可以直接./xxx.py来运行,因为这个头指定了python解释器的位置。接下来说说这两者的区别:
通常认为#!/usr/bin/env python 要比 #!/usr/bin/python要好 因为有的时候python并不是安装在默认路径下面的,例如在virtualenv中。
而#!/usr/bin/python表示是写死了你要这个目录下的python来执行你的脚本,但通常这不是明智的选择。
这种写法在你机器上安装了多个版本的python的时候有意义,这样声明的时候,会去取你机器的 PATH 中指定的第一个 python 来执行你的脚本。如果这时候你又配置了虚拟环境的话,那么这样写可以保证脚本会使用你虚拟环境中的 python 来执行。
所以这样看来,只有第二种方法才是正确的写法。
14、openpyxl
python有好几个包都是用来处理excel的,比如xlrd xlwt xlutils,但是
- 它们都比较老,xlwt甚至不支持07版以后的excel
- 它们的文档不太友好,都可能需要去读源代码
openpyxl,支持07+的excel,一直有人在维护,文档清晰易读,参照Tutorial和API文档很快就能上手
15、range(xxx) 和len()函数
range由字面意思可见代表一个范围,
函数原型:range(start, end, scan):
先列几个range()函数的几个用法:
参数含义:start:计数从start开始。默认是从0开始。例如range(5)等价于range(0, 5);
end:技术到end结束,但不包括end.例如:range(0, 5) 是[0, 1, 2, 3, 4]没有5
scan:每次跳跃的间距,默认为1。例如:range(0, 5) 等价于 range(0, 5, 1)
for i in range(5):print ii += 2print iprint '一轮结束'
结果:
为什么不是下面的结果?
而不是:
原因:每次for时i都被重新赋值了 这点在使用的时候需要注意,和c/c++/java里的for虚幻稍有不同
len()
描述
Python len() 方法返回字符串、列表、字典、元组等长度
语法
len()方法语法:
len( xxx )
16、float()\int()
转化为float和int类型
17、None
None是一个特殊的常量。
None和False不同。
None不是0。
None不是空字符串。
None和任何其他的数据类型比较永远返回False。
None有自己的数据类型NoneType。
你可以将None复制给任何变量,但是你不能创建其他NoneType对象。
- >>> type(None)
- <class 'NoneType'>
- >>> None == 0
- False
- >>> None == ''
- False
- >>> None == None
- True
- >>> None == False
- False
None是一个空的对象,代表什么都没有
18、raw_input() 和 input()
两个都是读取用户输入不同点在于raw_input在处理输入时候总将输入作为字符串来处理,而input在遇到数字的时候会将其作为数字处理,如raw_input(3+4)返回字符串'3+4',input(3+4)返回7
而对于 input() ,它希望能够读取一个合法的 python 表达式,即你输入字符串的时候必须使用引号将它括起来,否则它会引发一个 SyntaxError
19、with。。。。as。。。。
简单的来说这个语法是用来代替传统的try。。。finally。。。语法的
with是从Python 2.5 引入的一个新的语法,更准确的说,是一种上下文的管理协议,用于简化try…except…finally的处理流程。with通过__enter__方法初始化,然后在__exit__中做善后以及处理异常。对于一些需要预先设置,事后要清理的一些任务,with提供了一种非常方便的表达。
在Python有2种方式来实现with语法:class-based和decorator-based,2种方式在原理上是等价的,可以根据具体场景自己选择
with最初起源于一种block…as…的语法,但是这种语法被很多人所唾弃,最后诞生了with,关于这段历史依然可以去参考PEP-343和PEP-340
20、yield
带有 yield 的函数在 Python 中被称之为 generator(生成器)
具体参考:http://www.ibm.com/developerworks/cn/opensource/os-cn-python-yield/
---------------未完待续-------------
python代码解析相关推荐
- 【Android 逆向】使用 Python 代码解析 ELF 文件 ( PyCharm 中进行断点调试 | ELFFile 实例对象分析 )
文章目录 一.PyCharm 中进行断点调试 二.ELFFile 实例对象分析 一.PyCharm 中进行断点调试 在上一篇博客 [Android 逆向]使用 Python 代码解析 ELF 文件 ( ...
- 密码算法中iv值是什么_?标检测中的?极?值抑制算法(nms):python代码解析
⾮极⼤值抑制(Non-Maximum Suppression)原理 ⾮极⼤值抑制,顾名思义,找出极⼤值,抑制⾮极⼤值.这种思路和算法在各个领域中应⽤⼴泛,⽐如边缘检测算法canny算⼦中就使⽤了该⽅法 ...
- nms python代码_?标检测中的?极?值抑制算法(nms):python代码解析
⾮极⼤值抑制(Non-Maximum Suppression)原理 ⾮极⼤值抑制,顾名思义,找出极⼤值,抑制⾮极⼤值.这种思路和算法在各个领域中应⽤⼴泛,⽐如边缘检测算法canny算⼦中就使⽤了该⽅法 ...
- 【Android 逆向】使用 Python 代码解析 ELF 文件 ( PyCharm 中创建 Python 程序 | 导入 ELFFile 库 | 解析 ELF 文件 )
文章目录 一.PyCharm 中创建 Python 程序 二.导入 ELFFile 依赖库 三. 解析 ELF 文件 四. 博客源码 一.PyCharm 中创建 Python 程序 在 PyCharm ...
- Python代码解析数据
{"jwotestProduct":null,"score":0,"comments":[{"id":130457723 ...
- 独家 | 手把手教你使用OpenCV库(附实例、Python代码解析)
作者:Anirudh Rao 翻译:吴金笛 校对:李洁 本文约4000字,建议阅读10+分钟. 本文将通过几个简单的实例带你上手OpenCV库,新手必备!
- 气象数据Grib格式解析的Python代码和Matlab代码
以.grb/.grb1/.grb2为扩展名的都是气象数据,气象数据中可以存储多个内容,如云量.雪深.气压.风速等内容,或者具有时间序列的云量等.这些文件不可以直接打开成图片,若想直观地查看grib数据 ...
- 机器学习系列(12)_XGBoost参数调优完全指南(附Python代码)
机器学习系列(12)_XGBoost参数调优完全指南(附Python代码) 原文链接:http://blog.csdn.net/han_xiaoyang/article/details/5266539 ...
- 几行 Python 代码实现邮件解析,超赞~
作者 | Yunlor 来源 | CSDN博客 前言 如何通过python实现邮件解析?邮件的格式十分复杂,主要是mime协议,本文主要是从实现出发,具体原理可以自行研究. 一.安装 通过mailgu ...
最新文章
- 2021年春季学期-信号与系统-第三次作业参考答案-第十道题
- WebSocket 原理
- struct结构体数据类型
- 数据处理算法链接 DATA MINING GA LINK
- linux安卓双系统板子,安卓迷你 PC 主机只要 109 美元,支持 Android 和 Linux 双系统...
- linux 进程崩溃log,linux调试:dmesg 查看程序崩溃原因分析方法之一
- 使用swiftenv管理swift版本
- SQL Server 2014数据访问层
- 程序员编程表达爱情php,2019浪漫情人节:8款程序员必备表白源码
- python画图实战_python实战学习之matplotlib绘图续
- python装饰器快速入门
- linux apache访问日志,linux分析apache日志获取最多访问的前10个IP
- 拓端tecdat|R语言基于树的方法:决策树,随机森林,Bagging,增强树
- python通讯录课程设计
- 新店铺怎么做?淘宝店铺如何引流做好基础销量?
- 财会法规与职业道德【6】
- ubuntu 18.04 安装搜狗拼音输入法(没有坑)
- 使用阿里云,5分钟搭建私有云盘
- P6857 梦中梦与不再有梦
- 使用 dotnet *.dll启动项目,修改产品模式为开发模式