Web Spider实战1——简单的爬虫实战(爬取"豆瓣读书评分9分以上榜单")
1、Web Spider简介
Web Spider,又称为网络爬虫,是一种自动抓取互联网网页信息的机器人。它们被广泛用于互联网搜索引擎或其他类似网站,以获取或更新这些网站的内容和检索方式。它们可以自动采集所有其能够访问到的页面内容,以供搜索引擎做进一步处理(分检整理下载的页面),而使得用户能更快的检索到他们需要的信息。
2、一个简单的网络爬虫案例
作者在浏览网页的时候看到豆瓣书单的网页(首页),如下所示:
因为书单共有409本书,17个页面,若是要一个个浏览完,需要较长的时间,想要保存好书单,那是一件比较困难的事情,因此,想到是不是可以利用爬虫(Web Spider)把书名都保存下来,说干就干,下面详细介绍一下如何利用Python爬取书单。
3、单页面的抓取和分析
3.1、抓取
首先是单个页面的抓取,这里使用到了Python的urllib2库,urllib2库将网页以HTML的形式抓取到本地,代码如下:
def spider(url, user_agent="wswp"):
print "Downloading: ", url
# 设置代理
headers = {"User-agent": user_agent}
request = urllib2.Request(url, headers=headers)
html = ""
try:
html = urllib2.urlopen(request).read()
except urllib2.URLError as e:
print "Download error: ", e.reason
html = None
return html
在抓取的过程中,使用到了Request方法,urlopen方法和read方法。通过以上简单的抓取,将网页以HTML的格式抓取到本地。
3.2、对抓取的页面分析
在分析模块中主要是使用到了正则表达式,使用到了Python中的re库,利用正则表达式提取出书的名字,如:
页面的分析代码如下:
def parse_page(html):
html = html.replace("r", "")
html = html.replace("n", "")
html = html.replace(" 13", "")
result = re.findall('<div class="title">(.*?)</div>', html)
book_list = []
for x in result:
# 得到书名
book_name = re.findall('<a.*?>(.+)</a>', x.strip())
book_list.append(book_name[0].strip())
return book_list
最终得到了页面上的25本书的名字,如下:
3.3、主过程
在整个过程中使用到的模块为:
import urllib2
import re
主过程为:
if __name__ == "__main__":
seed = "https://www.douban.com/doulist/1264675/?start=0&sort=seq&sub_type="
html = spider(seed)
book_list = parse_page(html)
print len(book_list)
for x in book_list:
print x
4、抓取完整的书单
上面介绍了抓取其中一个页面的过程,为了能够抓取到完整的目录,需要解析所有的网页的网址,并对每一个网址都进行抓取,其中,网页的网址在页面下方的导航中:
在HTML代码中的格式为:
因此需要在分析模块中增加分析网址的功能,因此改进后的parse_page函数为:
def parse_page(html, url_map):
# 1、去除无效的字符
html = html.replace("r", "")
html = html.replace("n", "")
html = html.replace(" 13", "")
# 2、解析出书名
result_name = re.findall('<div class="title">(.*?)</div>',html)
book_list = []
for x in result_name:
# 提取出书名
book_name = re.findall('<a.*?>(.+)</a>', x.strip())
book_list.append(book_name[0].strip())
# 3、解析出还有哪些网址
result_url = re.findall('<div class="paginator">(.*?)</div>', html)
url_list = re.findall("[a-zA-z]+://[^s"]*", result_url[0])
for x in url_list:
x = x.strip()
if x not in url_map:
url_map[x] = 0
return book_list, url_map
在解析出书名后,解析出网址。
4.2、控制
在利用函数parse_page函数抓取一个网页后,分析出网页中的书单,同时,将网页中链向其他页面的网址提取出来,这样,我们需要一个控制模块,能够对提取出的网址依次抓取,分析,提取。这样的控制模块的代码如下:
def control(seed):
# 设置map用于记录哪些网址需要爬取
url_map = {}
book_list = []
# 爬取种子网址
html = spider(seed)
url_map[seed] = 1 #种子网址已经爬取过
# 解析种子网址
book_tmp, url_map = parse_page(html, url_map)
for x in book_tmp:
book_list.append(x)
# 对url_map中的的网址依次爬取
while True:
for k, v in url_map.items():
if v == 0:
# 爬取
html = spider(k)
url_map[k] = 1
book_tmp, url_map = parse_page(html, url_map)
for x in book_tmp:
book_list.append(x)
break
else:
continue
if 0 not in url_map.values():
break
return book_list
通过一个map存储所有页面的网址,key为网址,value为是否抓取过,0表示未抓取,1表示的是已抓取过。通过循环分析该map,直到所有的key对应的页面都被抓取过为止。
4.3、主函数
主函数为:
if __name__ == "__main__":
seed = "https://www.douban.com/doulist/1264675/?start=0&sort=seq&sub_type="
book_list = control(seed)
print len(book_list)
for x in book_list:
print x
最终抓取到的书单的个数为408个,但是首页上显示有409本:
调研发现有一本书没有:
因此,整个抓取没有问题。
最终的书单的部分如下:
在上面实现了一个简单的爬虫,当然,想要抓取更多更复杂的网站,这个爬虫是不行的,接下来,我们会慢慢深入到爬虫的更多的技术。
- ExtJs学习笔记(7)_获取GridPanel选中行的详细信息
- ExtJs学习笔记(5)_Ajax示例
- shell脚本之特殊符号总结性梳理
- Centos6.X 下安装并使用VNC的操作记录
- Linux系统是否被植入木马的排查流程梳理
- 添加php的memcached扩展模块
- Android TextView中显示图片
- Nginx配置中的log_format用法梳理(设置详细的日志格式)
- 分享一个刷网页PV的python小脚本
- mysql完整备份时过滤掉某些库
- Jquery 结合Json控制Select下拉框
- ExtJs学习笔记(23)-ScriptTagProxy+XTemplate+WCF跨域取数据
- Centos7.2下Jumpserver V4.0环境安装部署记录
- 利用JQuery实现更简单的Ajax跨域请求
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- ES5中的继承
- Linux定时自动删除旧垃圾文件的Autotrash工具
- Thinking in DAX with PowerBI - 逻辑框架 - 计算逻辑
- Linux并发执行很简单,这么做就对了
- 一条命令让你明白shell中read命令的常用参数
- 防抖与节流
- 一道题理解Linux中sort命令的多个参数
- Centos7服务器下启动jar包项目的最佳方法
- JavaScript易错点(长期更新)
- Centos7.5配置java环境安装tomcat的讲解
- CSS3卡片光照效果
- Linux文本查找命令find的用法详解
- Canvas系列(2):曲线图形
- Shell中去除字符串里的空格或指定字符的方法
- 使用‘fsck’修复Linux中文件系统错误的方法