博客和其他经常更新的网站通常有一个首页,其中有最新的帖子,以及一个“前
一篇”按钮,将你带到以前的帖子。然后那个帖子也有一个“前一篇”按钮,以此类推。这创建了一条线索,从最近的页面,直到该网站的第一个帖子。如果你希望拷贝该网站的内容,在离线的时候阅读,可以手工导航至每个页
面并保存。但这是很无聊的工作,所以让我们写一个程序来做这件事。
XKCD 是一个流行的极客漫画网站,它符合这个结构(参见图 11-6)。首页 
http://xkcd.com/有一个“Prev”按钮,让用户导航到前面的漫画。手工下载每张漫画要花较长的时间,但你可以写一个脚本,在几分钟内完成这件事。
下面是程序要做的事:
•    加载主页;
•    保存该页的漫画图片;
•    转入前一张漫画的链接;
•    重复直到第一张漫画。

这意味着代码需要做下列事情:
•    利用 requests 模块下载页面。
•    利用Beautiful Soup 找到页面中漫画图像的 URL。
•    利用 iter_content()下载漫画图像,并保存到硬盘。
•    找到前一张漫画的链接 URL,然后重复。
打开一个新的文件编辑器窗口,将它保存为downloadXkcd.py。

第 1 步:设计程序
打开一个浏览器的开发者工具,检查该页面上的元素,你会发现下面的内容:
•    漫画图像文件的 URL,由一个<img>元素的 href 属性给出。
•    <img>元素在<div id="comic">元素之内。
•    Prev 按钮有一个 rel HTML 属性,值是 prev。
•    第一张漫画的 Prev 按钮链接到 http://xkcd.com/# URL,表明没有前一个页面了。让你的代码看起来像这样:
#!  python3
#  downloadXkcd.py  -  Downloads  every  single  XKCD  comic. import  requests,  os,  bs4
url  =  'http://xkcd.com'                            #  starting  url os.makedirs('xkcd',  
exist_ok=True)      #  store  comics  in  ./xkcd while  not  url.endswith('#'):
#  TODO:  Download  the  page.

#  TODO:  Find  the  URL  of  the  comic  image.

#  TODO:  Download  the  image.

#  TODO:  Save  the  image  to  ./xkcd. #  TODO:  Get  the  Prev  button's  url.
print('Done.')
你会有一个 url 变量,开始的值是'http://xkcd.com',然后反复更新(在一个 for循环中),变成当前页面的 Prev 链接的 URL。在循环的每一步,你将下载 URL 
上的漫画。如果 URL 以'#'结束,你就知道需要结束循环。
将图像文件下载到当前目录的一个名为 xkcd  的文件夹中。调用 os.makedirs()函数。确保这个文件夹存在,并且关键字参数 exist_ok=True 
在该文件夹已经存在时,防止该函数抛出异常。剩下的代码只是注释,列出了剩下程序的大纲。

第 2 步:下载网页
我们来实现下载网页的代码。让你的代码看起来像这样:
#!  python3
#  downloadXkcd.py  -  Downloads  every  single  XKCD  comic. import  requests,  os,  bs4
url  =  'http://xkcd.com'                            #  starting  url os.makedirs('xkcd',  
exist_ok=True)      #  store  comics  in  ./xkcd while  not  url.endswith('#'):
#  Download  the  page. print('Downloading  page  %s...'  %  url) res  =  requests.get(url) 
res.raise_for_status()

soup  =  bs4.BeautifulSoup(res.text)

#  TODO:  Find  the  URL  of  the  comic  image. #  TODO:  Download  the  image.
#  TODO:  Save  the  image  to  ./xkcd. #  TODO:  Get  the  Prev  button's  url.
print('Done.')
首先,打印url,这样用户就知道程序将要下载哪个 URL。然后利用requests 模块的 request.get()函数下载它。像以往一样,马上调用Response 
对象的raise_for_status()方法,如果下载发生问题,就抛出异常,并终止程序。否则,利用下载页面的文本创建一个 BeautifulSoup 对象。

第 3 步:寻找和下载漫画图像
让你的代码看起来像这样:

#!  python3
#  downloadXkcd.py  -  Downloads  every  single  XKCD  comic. import  requests,  os,  bs4
--snip--

#  Find  the  URL  of  the  comic  image. comicElem  =  soup.select('#comic  img') if  comicElem  
==  []:
print('Could  not  find  comic  image.') else:
comicUrl  =  'http:'  comicElem[0].get('src') #  Download  the  image.
print('Downloading  image  %s...'  %  (comicUrl)) res  =  requests.get(comicUrl) 
res.raise_for_status()

#  TODO:  Save  the  image  to  ./xkcd. #  TODO:  Get  the  Prev  button's  url.
print('Done.')
用开发者工具检查 XKCD 主页后,你知道漫画图像的<img>元素是在一个<div>元素中,它带有的 id  属性设置为 comic。所以选择器'#comic  img'将从 
BeautifulSoup对象中选出正确的<img>元素。
有一些XKCD 页面有特殊的内容,不是一个简单的图像文件。这没问题,跳过它们就好了。如果选择器没有找到任何元素,那么 soup.select('#comic 
img')将返回一个空的列表。出现这种情况时,程序将打印一条错误消息,不下载图像,继续执行。
否则,选择器将返回一个列表,包含一个<img>元素。可以从这个<img>元素中取得 src 属性,将它传递给 requests.get(),下载这个漫画的图像文件。

第 4 步:保存图像,找到前一张漫画
让你的代码看起来像这样:
#!  python3
#  downloadXkcd.py  -  Downloads  every  single  XKCD  comic. import  requests,  os,  bs4
--snip--

#  Save  the  image  to  ./xkcd.
imageFile  =  open(os.path.join('xkcd',  os.path.basename(comicUrl)),  'wb') for  chunk  in  
res.iter_content(100000):
imageFile.write(chunk) imageFile.close()

#  Get  the  Prev  button's  url.
prevLink  =  soup.select('a[rel="prev"]')[0]
url  =  'http://xkcd.com'  +  prevLink.get('href')

print('Done.')

这时,漫画的图像文件保存在变量 res 中。你需要将图像数据写入硬盘的文件。你需要为本地图像文件准备一个文件名,传递给 open()。comicUrl  的值类似
'http://imgs.xkcd.com/comics/heartbleed_explanation.png'。你可能注意到,它看起来很像文件路径。实际上,调用 
os.path.basename()时传入 comicUrl,它只返回 URL 的最后部分:'heartbleed_explanation.png'。你可以用它作为文件名,将图像保存到硬盘。用 
os.path.join()连接这个名称和 xkcd 文件夹的名称,这样程序就会在 Windows下使用倒斜杠(\),在  OS X 和 Linux 
下使用斜杠(/)。既然你最后得到了文件名,就可以调用 open(),用'wb'模式打开一个新文件。
回忆一下本章早些时候,保存利用 Requests 下载的文件时,你需要循环处理 iter_content()方法的返回值。for 循环中的代码将一段图像数据写入文件(每次最多 10 
万字节),然后关闭该文件。图像现在保存到硬盘中。
然后,选择器'a[rel="prev"]'识别出 rel 属性设置为 prev 的<a>元素,利用这个<a>元素的 href 属性,取得前一张漫画的 URL,将它保存在 url 中。然后 while 
循环针对这张漫画,再次开始整个下载过程。
这个程序的输出看起来像这样:
Downloading  page  http://xkcd.com...
Downloading  image  http://imgs.xkcd.com/comics/phone_alarm.png... Downloading  page  
http://xkcd.com/1358/...
Downloading  image  http://imgs.xkcd.com/comics/nro.png... Downloading  page  
http://xkcd.com/1357/...
Downloading  image  http://imgs.xkcd.com/comics/free_speech.png... Downloading  page  
http://xkcd.com/1356/...
Downloading  image  http://imgs.xkcd.com/comics/orbital_mechanics.png... Downloading  page  
http://xkcd.com/1355/...
Downloading  image  http://imgs.xkcd.com/comics/airplane_message.png... Downloading  page  
http://xkcd.com/1354/...
Downloading  image  http://imgs.xkcd.com/comics/heartbleed_explanation.png...
--snip--
这个项目是一个很好的例子,说明程序可以自动顺着链接,从网络上抓取大量的数据。你可以从 Beautiful  Soup 的文档了解它的更多功能:http://www.  crummy.com/ 
software/BeautifulSoup/bs4/doc/.

第 5 步:类似程序的想法
下载页面并追踪链接,是许多网络爬虫程序的基础。类似的程序也可以做下面的事情:
•    顺着网站的所有链接,备份整个网站。
•    拷贝一个论坛的所有信息。
•    复制一个在线商店中所有产品的目录。
requests 和BeautifulSoup 模块很了不起,只要你能弄清楚需要传递给 requests.get()的 
URL。但是,有时候这并不容易找到。或者,你希望编程浏览的网站可能要求你先登录。selenium 模块将让你的程序具有执行这种复杂任务的能力。

11.7 项目:下载所有 XKCD 漫画相关推荐

  1. python练习项目八——下载所有XKCD 漫画

    项目:下载所有XKCD 漫画 背景 博客和其他经常更新的网站通常有一个首页,其中有最新的帖子,以及一个"前一篇"按钮,将你带到以前的帖子.然后那个帖子也有一个"前一篇&q ...

  2. 【下载所有XKCD漫画】 详细解析

    目录 1,实现目的 2,准备工作 2.1,确保所需模块已安装 2.2,脚本思路 3,全部代码 4,执行结果 1,实现目的 XKCD 是一个流行的极客漫画网站.首页 http://xkcd.com/有一 ...

  3. 【Python】下载所有 XKCD 漫画

    博客和其他经常更新的网站通常有一个首页,其中有最新的帖子,以及一个"前 一篇"按钮,将你带到以前的帖子.然后那个帖子也有一个"前一篇"按钮,以此 类推.这创建了 ...

  4. 实例:下载所有XKCD漫画

    import requests,os,bs4 url='http://xkcd.com' os.makedirs('xkcd') while not url.endswith('#'):print(' ...

  5. python-web-下载所有xkcd漫画

    下载所有xkcd漫画 # downloads every single xkcd comicimport requests,os,bs4 url='http://xkcd.com' # start u ...

  6. Python批量下载XKCD漫画只需20行命令

    XKCD是一个流行的极客漫画网站,其官网首页有一个 Prev 按钮,让用户导航到前面的漫画.如果你希望复制该网站的内容以在离线的时候阅读,那么可以手动导航至每个页面并保存.但手动下载每张漫画要花较长的 ...

  7. 15.7 项目:多线程 XKCD 下载程序

    在第 11 章,你编写了一个程序,从XKCD 网站下载所有的 XKCD 漫画.这是 一个单线程程序:它一次下载一幅漫画.程序运行的大部分时间,都用于建立网络连接来开始下载,以及将下载的图像写入硬盘.如 ...

  8. 从XKCD网站下载自动所有漫画图片---python实现

    经常跟新的网站通常有一个首页,其中有最新的帖子,以及一个"前一篇"(或上一页)按钮,用来跳转到以前的帖子.然后那个帖子也有一个"前一篇"的按钮,以此内推.这创建 ...

  9. Python项目实战:下载腾讯漫画的脚本及源码【女朋友在也不担心我花钱购买漫画了】

    目录 工具: 命令行帮助 GUI预览效果 全部源码: 下载源码: 代码仅供学习交流使用 下载腾讯漫画的脚本.空参运行进入交互式模式,支持的参数可以加-h或--help参数查看. 工具: python3 ...

  10. JEECG十二个开源项目下载大全

    JEECG 社区开源项目下载(总览) 反馈问题板块:http://www.jeecg.org/forum.php?mod=forumdisplay&fid=153 资源1: JEECG 微云快 ...

最新文章

  1. Word字体与像素的对应关系(转)
  2. 关于知识蒸馏,你想知道的都在这里!
  3. mysql5.7.12 64位解压版_mysql 5.7 64位 解压版安装
  4. 云原生时代,底层性能如何调优?
  5. java:为什么字符串比较时要用equals方法而不是==运算符
  6. pytorch —— transforms图像增强(一)
  7. Android 爆高危漏洞,华为小米皆中招;第三代苹果 AirPods 来了;SQLite 3.30.0 发布 | 极客头条...
  8. R 修改安装包默认存放位置的方法
  9. 计算机类毕业论文中期检查,计算机类毕业论文中期检查表
  10. Oracle 根据汉字返回对应拼音的 函数
  11. 计算机研究院分所烟台,综合新闻_中科院计算所烟台分所 烟台中科网络技术研究所...
  12. java 生成.pcap_java抓包后对pcap文件解析示例
  13. 怎样使用Markdown输入数学公式
  14. 论文翻译——Rapid 2D-to-3D conversion——快速2D到3D转换
  15. dell刀片服务器 重启 维护,已解决: dell 刀片服务器内网网络问题 - Dell Community
  16. RabbitMq中的warren模式和shovel模式
  17. 谈谈「心流」:如何在学习中体验快乐
  18. 性能测试工具:如何录制脚本?
  19. 实验十 基于Simulink的爬山法MPPT技术仿真
  20. PHP单例模式demo

热门文章

  1. C++文件操作之写文件
  2. 使用ffmpeg打开ts格式视频文件
  3. 计算机设备维护服务合同,设备维护服务合同
  4. LYNC 2010 中文测试版已经可以下载
  5. 51单片机——独立按键
  6. 新唐MS51FB9AE串口烧录程序
  7. RapidShare 真实链接抓取助手
  8. 环形电流计算公式_环形变压器计算公式
  9. 全国人口年龄结构及抚养比(1987-2019年)
  10. 后台权限管理系统设计(图文教程)