最近准备好好学学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()的灵魂,

  1. 参数 描述
  2. r 读取模式打开文件
  3. w 读写模式打开文件
  4. a 写入模式打开文件
  5. b 二进制模式打开文件(可以和其他模式并用)
  6. + 读/写模式(可以和其他模式并用)
  7. 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,但是

  1. 它们都比较老,xlwt甚至不支持07版以后的excel
  2. 它们的文档不太友好,都可能需要去读源代码

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对象。

Python代码  
  1. >>> type(None)
  2. <class 'NoneType'>
  3. >>> None == 0
  4. False
  5. >>> None == ''
  6. False
  7. >>> None == None
  8. True
  9. >>> None == False
  10. 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代码解析相关推荐

  1. 【Android 逆向】使用 Python 代码解析 ELF 文件 ( PyCharm 中进行断点调试 | ELFFile 实例对象分析 )

    文章目录 一.PyCharm 中进行断点调试 二.ELFFile 实例对象分析 一.PyCharm 中进行断点调试 在上一篇博客 [Android 逆向]使用 Python 代码解析 ELF 文件 ( ...

  2. 密码算法中iv值是什么_?标检测中的?极?值抑制算法(nms):python代码解析

    ⾮极⼤值抑制(Non-Maximum Suppression)原理 ⾮极⼤值抑制,顾名思义,找出极⼤值,抑制⾮极⼤值.这种思路和算法在各个领域中应⽤⼴泛,⽐如边缘检测算法canny算⼦中就使⽤了该⽅法 ...

  3. nms python代码_?标检测中的?极?值抑制算法(nms):python代码解析

    ⾮极⼤值抑制(Non-Maximum Suppression)原理 ⾮极⼤值抑制,顾名思义,找出极⼤值,抑制⾮极⼤值.这种思路和算法在各个领域中应⽤⼴泛,⽐如边缘检测算法canny算⼦中就使⽤了该⽅法 ...

  4. 【Android 逆向】使用 Python 代码解析 ELF 文件 ( PyCharm 中创建 Python 程序 | 导入 ELFFile 库 | 解析 ELF 文件 )

    文章目录 一.PyCharm 中创建 Python 程序 二.导入 ELFFile 依赖库 三. 解析 ELF 文件 四. 博客源码 一.PyCharm 中创建 Python 程序 在 PyCharm ...

  5. Python代码解析数据

    {"jwotestProduct":null,"score":0,"comments":[{"id":130457723 ...

  6. 独家 | 手把手教你使用OpenCV库(附实例、Python代码解析)

    作者:Anirudh Rao 翻译:吴金笛 校对:李洁 本文约4000字,建议阅读10+分钟. 本文将通过几个简单的实例带你上手OpenCV库,新手必备!

  7. 气象数据Grib格式解析的Python代码和Matlab代码

    以.grb/.grb1/.grb2为扩展名的都是气象数据,气象数据中可以存储多个内容,如云量.雪深.气压.风速等内容,或者具有时间序列的云量等.这些文件不可以直接打开成图片,若想直观地查看grib数据 ...

  8. 机器学习系列(12)_XGBoost参数调优完全指南(附Python代码)

    机器学习系列(12)_XGBoost参数调优完全指南(附Python代码) 原文链接:http://blog.csdn.net/han_xiaoyang/article/details/5266539 ...

  9. 几行 Python 代码实现邮件解析,超赞~

    作者 | Yunlor 来源 | CSDN博客 前言 如何通过python实现邮件解析?邮件的格式十分复杂,主要是mime协议,本文主要是从实现出发,具体原理可以自行研究. 一.安装 通过mailgu ...

最新文章

  1. 2021年春季学期-信号与系统-第三次作业参考答案-第十道题
  2. WebSocket 原理
  3. struct结构体数据类型
  4. 数据处理算法链接 DATA MINING GA LINK
  5. linux安卓双系统板子,安卓迷你 PC 主机只要 109 美元,支持 Android 和 Linux 双系统...
  6. linux 进程崩溃log,linux调试:dmesg 查看程序崩溃原因分析方法之一
  7. 使用swiftenv管理swift版本
  8. SQL Server 2014数据访问层
  9. 程序员编程表达爱情php,2019浪漫情人节:8款程序员必备表白源码
  10. python画图实战_python实战学习之matplotlib绘图续
  11. python装饰器快速入门
  12. linux apache访问日志,linux分析apache日志获取最多访问的前10个IP
  13. 拓端tecdat|R语言基于树的方法:决策树,随机森林,Bagging,增强树
  14. python通讯录课程设计
  15. 新店铺怎么做?淘宝店铺如何引流做好基础销量?
  16. 财会法规与职业道德【6】
  17. ubuntu 18.04 安装搜狗拼音输入法(没有坑)
  18. 使用阿里云,5分钟搭建私有云盘
  19. P6857 梦中梦与不再有梦
  20. 使用 dotnet *.dll启动项目,修改产品模式为开发模式

热门文章

  1. cocos入门7:cocos creator 中的ui系统
  2. laravel框架实践1
  3. 免费试用丨阿拉丁统计2.0 产品全新升级,五大优势功能满足多种需求
  4. 学什么编程语言最有前途?
  5. C语言 用字符串打印ASCII码值
  6. 大数据与海量数据的区别
  7. 激光打标机使标记处理智能化
  8. linux 保存文件名乱码怎么办,Linux下文件名乱码的解决方法
  9. 【OpenCV】Ubuntu配置OpenCV环境
  10. oracle----存储过程