kindle网络爬虫续集
简单介绍:
这次我们要爬的网页是:Kindle商店中的今日特价书,其中每周/每月特价书同理,就不再重复了
选择这个网页的原因有两个:
一是实用,很多人都会经常去看看Kindle特价书有没有自己喜欢的;
二是简单,不需要分析JS脚本
这次我们学习的基本内容涉及:
urllib2获取网页、re正则表达式、图像获取
阅读前的建议">阅读前的建议:
必备条件:Python的基础知识,学习网站:Python 2.7教程 - 廖雪峰的官方网站 建议学习正则表达式 更完整的爬虫教程:静觅 文章中注释用灰色表示,对代码的理解用深青色,正则表达式相关内容用淡钢蓝 urllib2对亚马逊的访问并不稳定,有时会出现httplib错误,重新运行即可
开发工具
IDE: PyCharm(JetBrain公司的IDE)浏览器:Chrome或者360极速浏览器
正文:
看起来有那么一点奇怪,联想到这个页面是每日更新的,所以我怀疑这个URL每天都会不同,因此我们不能直接访问这个URL。
那么现在我们就应该找一个固定的URL作为起点,然后进行抓取;Kindle商店的URL好像也是不固定的,看起来唯一的选择是亚马逊首页了
我们的思路可以基本捋出来了:
1. 访问亚马逊首页,获取Kindle商店 URL
2. 访问Kindle商店,获取“今日特价书”URL
3. 分析今日特价书的页面,获取书的详细信息
4. 图片的获取
访问亚马逊首页
Python自带了一个名叫urllib2的库,专门用于从网页中获取信息
我们想要获取一个网页的源码,最简单的方式就是:
url1 = 'https://www.amazon.cn' #定义字符串url
response1 = urllib2.urlopen(url1) #打开网站首页 获取源代码
我对于这段代码的理解是:
urllib2的urlopen方法将网页的响应封装成类似文件的结构,我们要读取里面的内容时直接read()就好
网页获取的基本知识:
1. GET / POST
访问网页的方式有两种,一种是GET,另一种是POST
GET方法直接请求服务器的网址
POST方法则向服务器发送信息并接收服务器的响应
具体在urllib2中,GET就是简单的urllib2.urlopen(url)
POST则需要将需要提交的表单的所有信息封装成字典values = {'name': 'value', 'name':'value',...}
并且使用postdata = urllib.urlencode(values)
然后才能urllib2.urlopen(url, postdata)
POST适用于访问需要简单的登陆的网站如大多数学校的教务处
2. headers
有些网页为了防止爬虫采用验证浏览器头的方法,所以我们有时候需要改变浏览器头:headers = {'User-Agent' : user_agent}
request = urllib2.Request(url, headers=headers)
response = urllib2.urlopen(amazonRequest)
在这里我们构建了一个Request,并且用urlopen发送(如果需要POST可以在构建时加上data=postdata)
那么现在,我们就获得了亚马逊首页的源码,打开谷歌浏览器后选择查看网页源代码
接着就是关键的一步了,用正则表达式获取Kindle商店的URL。
我们先来看看亚马逊首页,我们在首页是这样访问Kindle商店的:
所以我们直接在源代码里面搜索“Kindle 商店”(注意中间的空格不能少),然后我们来到这里:
我们获取的就是后面“url1”的内容,所以我们写如下正则表达式:
KindlePattern1 = re.compile('Kindle 商店.*?url1":"(.*?)"', re.S) # re.compile(string, flags)创建模式,pattern一般用re.S(多行选择)
KindleURL1 = url1 + re.search(KindlePattern1, response1.read()).group(1) # 根据正则表达式模式匹配到应用商店的网址
print '应用商店的网址:\n %s' % KindleURL1 #将匹配好的数据打印出来
Python的正则表达式很简单(一般都是遵循这三个步骤):
1. re.compile(string, flags)创建模式,pattern一般用re.S(多行选择)
2. re.search(pattern, string)根据模式在string中匹配到则停止
3. re.findall(pattern, string)返回一个List,里面包含所有符合的子字符串
4. 常用的字符: “.”代表任意字符, “*”代表个数为任意个, “?”代表零次或一次匹配前面的字符或子表达式, 括号”()”内的则为返回内容
group(): 仅在search后有效,findall无group()
group(0)表示匹配到的所有内容
group(1)表示第一个(.*?)所返回的内容,2则表示第二个,依此类推
访问Kindle商店,获取“今日特价书”URL
上面我们知道了Kindle商店的URL,现在我们来获取今日特价书的URL
url2 = KindleURL1
response2 = urllib2.urlopen(url2)
然后继续上面的步骤,将网页源码中搜索“今日特价书”,然后发现得到一个标签:
今日特价书
我们来提取一下
url2 = KindleURL1
response2 = urllib2.urlopen(url2)
discountPattern = re.compile('什么值得读.*?href="(.*?)">今日特价书', re.S)
bookURL = url1 + re.search(discountPattern, response2.read()).group(1)
print '今日特价的网址:\n %s' % bookURL
分析今日特价书的页面,获取书的详细信息
老方法获取页面的源码:
response3 = urllib2.urlopen(bookURL) #获取今日特价网站的源代码
然后使用chrome分析页面,再查找,写出正则表达式
response3 = urllib2.urlopen(bookURL) #获取今日特价网站的源代码
infoPattern = re.compile('productImage">.*?href="(.*?)".*?src="(.*?)".*?productTitle">.*?>(.*?)<.*?productByLine">(.*?)<.*?a-color-price">(.*?)<',re.S)
infos = re.findall(infoPattern, response3.read())
for info in infos:
print '链接:' + url1 + info[0].strip('\n')
print '图片地址:' + info[1].strip('\n')
print '书名:' + info[2].strip('\n')
print '作者:' + info[3].strip('\n')
print '价格: ' + info[4].strip('\n')
我们得到的结果是:
图片的获取
在上面我们已经得到书本图片的URL,接下来要做的就是把图片保存
urllib2将网页封装成类似文件的格式,所以图片保存的过程就像从一个文件中读取然后打开另一个文件写入一样简单
在for循环后插入这段代码
imgURL = info[1].strip('\n') # 获得图片链接
imgNamePattern = re.compile('/I/(.*?)jpg',re.S) # 用正则表达式提取图片名称
imgName = re.search(imgNamePattern, imgURL) # 提取图片名称
response = urllib2.urlopen(imgURL) # 打开图片链接
with open(imgName.group(1)+'jpg', 'wb') as file: # 以二进制写方式打开
file.write(response.read()) # 写入文件
可能你已经注意到了,为什么要用'/I/(.?)jpg'作为正则模板?为什么不能直接用
'I/(.?)'
正则表达式中不能直接提取到字符串结束,否则会报错,这是刚刚在写这段代码的时候发现的,所以我们选择
jpg为终结标志
现在去文件夹看看,发现两本书的图片都已经有了。
kindle网络爬虫续集的更多相关文章
- 转:【Python3网络爬虫开发实战】 requests基本用法
1. 准备工作 在开始之前,请确保已经正确安装好了requests库.如果没有安装,可以参考1.2.1节安装. 2. 实例引入 urllib库中的urlopen()方法实际上是以GET方式请求网页,而 ...
- Python初学者之网络爬虫(二)
声明:本文内容和涉及到的代码仅限于个人学习,任何人不得作为商业用途.转载请附上此文章地址 本篇文章Python初学者之网络爬虫的继续,最新代码已提交到https://github.com/octans ...
- 网络爬虫:使用Scrapy框架编写一个抓取书籍信息的爬虫服务
上周学习了BeautifulSoup的基础知识并用它完成了一个网络爬虫( 使用Beautiful Soup编写一个爬虫 系列随笔汇总 ), BeautifulSoup是一个非常流行的Python网 ...
- 网络爬虫: 从allitebooks.com抓取书籍信息并从amazon.com抓取价格(3): 抓取amazon.com价格
通过上一篇随笔的处理,我们已经拿到了书的书名和ISBN码.(网络爬虫: 从allitebooks.com抓取书籍信息并从amazon.com抓取价格(2): 抓取allitebooks.com书籍信息 ...
- 网络爬虫: 从allitebooks.com抓取书籍信息并从amazon.com抓取价格(2): 抓取allitebooks.com书籍信息及ISBN码
这一篇首先从allitebooks.com里抓取书籍列表的书籍信息和每本书对应的ISBN码. 一.分析需求和网站结构 allitebooks.com这个网站的结构很简单,分页+书籍列表+书籍详情页. ...
- 网络爬虫: 从allitebooks.com抓取书籍信息并从amazon.com抓取价格(1): 基础知识Beautiful Soup
开始学习网络数据挖掘方面的知识,首先从Beautiful Soup入手(Beautiful Soup是一个Python库,功能是从HTML和XML中解析数据),打算以三篇博文纪录学习Beautiful ...
- Atitit.数据检索与网络爬虫与数据采集的原理概论
Atitit.数据检索与网络爬虫与数据采集的原理概论 1. 信息检索1 1.1. <信息检索导论>((美)曼宁...)[简介_书评_在线阅读] - dangdang.html1 1.2. ...
- Java 网络爬虫获取页面源代码
原博文:http://www.cnblogs.com/xudong-bupt/archive/2013/03/20/2971893.html 1.网络爬虫是一个自动提取网页的程序,它为搜索引擎从万维网 ...
- [Search Engine] 搜索引擎技术之网络爬虫
随着互联网的大力发展,互联网称为信息的主要载体,而如何在互联网中搜集信息是互联网领域面临的一大挑战.网络爬虫技术是什么?其实网络爬虫技术就是指的网络数据的抓取,因为在网络中抓取数据是具有关联性的抓取, ...
随机推荐
- php笔记(五)PHP类和对象之对象的高级特性
对象比较,当同一个类的两个实例的所有属性都相等时,可以使用比较运算符==进行判断,当需要判断两个变量是否为同一个对象的引用时,可以使用全等运算符===进行判断. class Car { } $a = ...
- Kruskal算法的简单实现
嘛嘛嘛,好像大家在实现Kruskal算法是都是用的边集数组,判断图的连通性咱不会,o(╯□╰)o(为什么咱这么菜诶) Kruskal算法: 规则: (1)对每一条边按照从小到大进行排序 (2)加入边的 ...
- Python基础(十三)-进程&线程
进程 定义:进程是程序在一个数据集合上的运行过程,是系统进行资源分配和调度的基本单位 线程
- mysql denied for user 'root'@'localhost'
Access[root@log01 ~]# mysql -u root -p Enter password: ERROR 1045 (28000): Access denied for user 'r ...
- Remote小Demo
Demo基于http://www.cnblogs.com/zhili/p/NETRemoting.html RemotingObj using System; using System.Collect ...
- Location-aware Associated Data Placement for Geo-distributed Data-intensive Applications--INFOCOM 2015
[标题] [作者] [来源] [对本文评价] [why] 存在的问题 [how] [不足] assumption future work [相关方法或论文] [重点提示] [其它]
- php 设置白名单ip
//检查白名单ip private function _checkAllowIp() { $allowIp = ['203.195.156.12']; $ip = $this->getIp(); ...
- CentOS 下网络报错 Device eth0 does not seem to be present
在执行network服务重启后,出现Device eth0 does not seem to be present 问题,主要是因为系统之前有多个网卡配置,和配置文件不匹配造成的. 解决这种问题,思 ...
- Delphi @ # $ 特殊字符含义
^: 指针 @: 取址 #: 十进制符 $: 十六进制符
- final使用
final修饰 基本数据类型时候 对应的 数据不能改变:::final修饰 对象类型 ,那么对应的引用地址不能改变(对象中的值可以改变): 如果final修改方法,那么该方法不能被子类重写 :: ...