简单介绍

这次我们要爬的网页是:Kindle商店中的今日特价书,其中每周/每月特价书同理,就不再重复了
选择这个网页的原因有两个:
一是实用,很多人都会经常去看看Kindle特价书有没有自己喜欢的;
二是简单,不需要分析JS脚本
这次我们学习的基本内容涉及:
urllib2获取网页、re正则表达式、图像获取


阅读前的建议">阅读前的建议

必备条件:Python的基础知识,学习网站:Python 2.7教程 - 廖雪峰的官方网站 建议学习正则表达式 更完整的爬虫教程:静觅 文章中注释用灰色表示,对代码的理解用深青色,正则表达式相关内容用淡钢蓝 urllib2对亚马逊的访问并不稳定,有时会出现httplib错误,重新运行即可


开发工具

IDE:  PyCharm(JetBrain公司的IDE)浏览器:Chrome或者360极速浏览器


正文

首先我们访问我们要抓取的页面,发现URL是:
https://www.amazon.cn/gp/feature.html/ref=amb_link_34492412_17?ie=UTF8&docId=126758&pf_rd_m=A1AJ19PSB66TGU&pf_rd_s=merchandised-search-top-1&pf_rd_r=SW95YM983VR5D6D93RAP&pf_rd_t=101&pf_rd_p=289836012&pf_rd_i=116087071

看起来有那么一点奇怪,联想到这个页面是每日更新的,所以我怀疑这个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')
strip表示去掉特定字符

我们得到的结果是:

 

图片的获取

在上面我们已经得到书本图片的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网络爬虫续集的更多相关文章

  1. 转:【Python3网络爬虫开发实战】 requests基本用法

    1. 准备工作 在开始之前,请确保已经正确安装好了requests库.如果没有安装,可以参考1.2.1节安装. 2. 实例引入 urllib库中的urlopen()方法实际上是以GET方式请求网页,而 ...

  2. Python初学者之网络爬虫(二)

    声明:本文内容和涉及到的代码仅限于个人学习,任何人不得作为商业用途.转载请附上此文章地址 本篇文章Python初学者之网络爬虫的继续,最新代码已提交到https://github.com/octans ...

  3. 网络爬虫:使用Scrapy框架编写一个抓取书籍信息的爬虫服务

      上周学习了BeautifulSoup的基础知识并用它完成了一个网络爬虫( 使用Beautiful Soup编写一个爬虫 系列随笔汇总 ), BeautifulSoup是一个非常流行的Python网 ...

  4. 网络爬虫: 从allitebooks.com抓取书籍信息并从amazon.com抓取价格(3): 抓取amazon.com价格

    通过上一篇随笔的处理,我们已经拿到了书的书名和ISBN码.(网络爬虫: 从allitebooks.com抓取书籍信息并从amazon.com抓取价格(2): 抓取allitebooks.com书籍信息 ...

  5. 网络爬虫: 从allitebooks.com抓取书籍信息并从amazon.com抓取价格(2): 抓取allitebooks.com书籍信息及ISBN码

    这一篇首先从allitebooks.com里抓取书籍列表的书籍信息和每本书对应的ISBN码. 一.分析需求和网站结构 allitebooks.com这个网站的结构很简单,分页+书籍列表+书籍详情页. ...

  6. 网络爬虫: 从allitebooks.com抓取书籍信息并从amazon.com抓取价格(1): 基础知识Beautiful Soup

    开始学习网络数据挖掘方面的知识,首先从Beautiful Soup入手(Beautiful Soup是一个Python库,功能是从HTML和XML中解析数据),打算以三篇博文纪录学习Beautiful ...

  7. Atitit.数据检索与网络爬虫与数据采集的原理概论

    Atitit.数据检索与网络爬虫与数据采集的原理概论 1. 信息检索1 1.1. <信息检索导论>((美)曼宁...)[简介_书评_在线阅读] - dangdang.html1 1.2. ...

  8. Java 网络爬虫获取页面源代码

    原博文:http://www.cnblogs.com/xudong-bupt/archive/2013/03/20/2971893.html 1.网络爬虫是一个自动提取网页的程序,它为搜索引擎从万维网 ...

  9. [Search Engine] 搜索引擎技术之网络爬虫

    随着互联网的大力发展,互联网称为信息的主要载体,而如何在互联网中搜集信息是互联网领域面临的一大挑战.网络爬虫技术是什么?其实网络爬虫技术就是指的网络数据的抓取,因为在网络中抓取数据是具有关联性的抓取, ...

随机推荐

  1. 反射机制(reflection)动态相关机制

    功能:动态获取类的信息以及动态调用对象的方法. Java反射机制主要提供了以下功能: 1.在运行时判断任意一个对象所属的类. 2.在运行时构造任意一个类的对象. 3.在运行时判断任意一个类所具有的成员 ...

  2. Java中的字面量

    在计算机科学中,字面量(literal)是用于表达源代码中一个固定值的表示法(natation).几乎所有计算机编程语言都具有对基本值的字面量表示,诸如:整数.浮点数以及字符串:而有很多也对布尔类型和 ...

  3. 从安装.net Core 到helloWord(Mac上)

    最近听说微软 正式发不了.netCore 1.0 于是就安装了 并安装了vs Code 用于编写一些.net程序 一. .netCore的安装: 首先需要通过brew安装openssl(相信homeB ...

  4. mysql安装和基本配置-redhat

    1.redhat yum替换参考 url:http://blog.csdn.net/zcyhappy1314/article/details/17580943 2.yum卸载mysql rpm -qa ...

  5. sql server 2008 R2 压缩备份数据库

    今天需要把一个省外项目的数据库从服务器上备份.拷贝到本机(跨地域传输数据库备份文件). 连上VPN,通过远程桌面连接,连接上服务器,发现数据库文件已经有20G以上大小了. 文件太大,公司网络也不稳定, ...

  6. PHP使用正则表达式验证电话号码(手机和固定电话)

    这个还不错,很有用. tel='验证的电话号码'; $isMob="/^1[3-8]{1}[0-9]{9}$/";  $isTel="/^([0-9]{3,4}-)?[0 ...

  7. 给图片使用border-radius 图片会变成圆的。

  8. 关于autoconf

    1 the difference between AC_ARG_ENABLE and AC_ARG_WITH AC_ARG_ENABLE是enable一个feature,该feature所对应的源码包 ...

  9. 《JS权威指南学习总结--6.5枚举属性》

    内容要点: 一.for/in循环 1.for/in循环可以在循环体中遍历对象中所有可枚举的属性(包括自有属性和继承的属性),把属性名称赋值给循环变量.对象继承的内置方法不可枚举,但在代码中给对象添加的 ...

  10. swift 学习线路

    //从(GCD,动画,通知,KVO..) 到闭包 到单子 再到 promise ,再到 reactive //从可选类型 到可选绑定 ,隐私可选解包 ,动态绑定,nil 聚合运算符 再到可选链 再到S ...