Python 网络爬虫 005 (编程) 如何编写一个可以 下载(或叫:爬取)一个网页 的网络爬虫
如何编写一个可以 下载(或叫:爬取)一个网页 的网络爬虫
使用的系统:Windows 10 64位
Python 语言版本:Python 2.7.10 V
使用的编程 Python 的集成开发环境:PyCharm 2016 04
我使用的 urllib 的版本:urllib2
注意: 我没这里使用的是 Python2 ,而不是Python3
一 . 简介
编写网络爬虫的第一步就是下载网页,这个过程叫做: 爬取 。
二 . 准备工作
要想爬取网站,首先要将网站下载下来。我们使用 Python 内置的:urllib2 模块 来下载网站的 URL。
注意: 无须下载任何第三方库哦。
参考网站:http://stackoverflow.com/questions/34475051/need-to-install-urllib2-for-python-3-5-1
三 . 最简单的下载网页的网络爬虫程序
新建一个文件:download_html.py。将下面的代码输入进去:
import urllib2
def download(url):
return urllib2.urlopen(url).read()
执行:
> C:\Python27\python.exe -i download_html.py
>>> html = download('http://www.aobosir.com')
>>> print html
<!DOCTYPE html>
<html>
<head>
</head>
<body>
</body>
<script>
window.location.href="http://blog.csdn.net/github_35160620"
</script>
</html>
>>>
这样的程序,不是每一次都很顺利的运行的。我们可能会在执行上面这个程序的时候,遇到一些无法控制的问题,这根据你爬取的网站的不同而定。
* 比如,有的网站使用的编码方式与你这个程序下载网站是读取网站的编码方式不同,就会导致乱码问题;
* 再比如说:如果你爬取的目标网站具有反爬虫机制,那么当你爬取它的时候,你会遇到503 Service Unavailable 问题;
* 再比如说:如果你爬虫的网站根本不存在,那么你会得到 404 Not Found 问题。
四 . 加入异常处理程序
所以,我们为了能让程序捕获到这些异常情况,需要加上异常处理的程序。最终程序会变成下面这个样子:
import urllib2
def download(url):
print 'Downloading: ', url
try:
html = urllib2.urlopen(url).read()
except urllib2.URLError as e:
print 'Download error', e.reason
html = None
return html
运行:
D:\WorkSpace\python_ws\web-scraping-with-python-learning\ch1>C:\Python27\python.exe -i 1-4-1-download_html.py
>>> html = download('http://www.aobosir.com/')
Downloading: http://www.aobosir.com/
>>> html = download('http://httpstat.us/500')
Downloading: http://httpstat.us/500
Download error Internal Server Error
>>> html = download('http://www.meetup.com/')
Downloading: http://www.meetup.com/
Download error Forbidden
>>>
现在,如果程序在下载目标网站时,遇到异常就能捕获到这个异常了,然后返回 None 。现在还没有处理这个异常。只是能过捕获到它。
当然,下载网页是,遇到的错误经常都是临时性的,比如对于我们上面说的 503 问题,我们只需要尝试重新下载就可以解决这个问题。当然了,我们不需要对所有问题都尝试去重新下载,比如 404 问题,目标网页根本不存在,所以,你没有必要再去尝试。
扩展:
互联网工程任务小组(英语:Internet Engineering Task Force,缩写为 IETF)定义了HTTP错误的完整列表,详细内容到这个网站查看:https://zh.wikipedia.org/wiki/HTTP%E7%8A%B6%E6%80%81%E7%A0%81
从这个列表中,我们可以了解到:4XX问题是客户端出现的问题;5XX问题是服务器出现了问题;而其他的,比如:1XX是消息;2XX是成功;3XX是重定向。
五 . 只有出现 5xx 错误码的时候,才执行重新下载程序
所以,我们需要让 download() 这个函数在遇到 5XX 错误的时候重新下载即可。
所以,我们再次完善我们的 download() 函数:
import urllib2
def download(url, num_retries=2):
print 'Downloading: ', url
try:
html = urllib2.urlopen(url).read()
except urllib2.URLError as e:
print 'Download error', e.reason
html = None
if num_retries > 0:
if hasattr(e, 'code') and 500 <= e.code < 600:
# recursively retry 5xx HTTP errors
return download(url, num_retries-1)
return html
现在,在 download() 函数遇到 5xx 错误码的时候,就会自动递归 download() 函数本身进行重试。 download() 函数增加的第2个参数就是迎来指定递归的次数的,默认尝试2次。
测试这段程序,使用这个网站来测试:http://httpstat.us/500 ,这个网站会始终返回 500 错误码:
>>> html = download('http://httpstat.us/500')
Downloading: http://httpstat.us/500
Download error Internal Server Error
Downloading: http://httpstat.us/500
Download error Internal Server Error
Downloading: http://httpstat.us/500
Download error Internal Server Error
>>> html = download('http://www.meetup.com/')
Downloading: http://www.meetup.com/
Download error Forbidden
>>>
六 . 设置 用户代理(user_agent)
为了让我们的网络爬虫更加健壮,在网络中下载网页更加畅通无阻,我们需要:设置 用户代理(user_agent)
Q: 什么是 用户代理(user_agent)?
A: 你访问目标网站,就是访问目标服务器。那么让你访问服务器的时候,服务器会读取你是使用什么来访问它的。比如:如果你使用是是Chrome 浏览器访问它的,那么目标服务器就知道:你是使用浏览器访问它的。服务器就是通过用户代理这个参数来得到你是通过什么访问它的。
用户代理 指的是:简单的说就是一个参数,并且这个参数我们是可以修改的。在默认情况下,我们使用urllib2写的爬虫,它默认将 Python-urllib/2.7 这个字符串做为爬虫程序的用户代理。
Q: 为什么要设置 用户代理(user_agent)?
A: 如果我们使用这个默认的 Python-urllib/2.7 这个字符串做为我们的爬虫程序的用户代理,我们的爬虫会碰到很多的问题的。有些网站为了不希望网络爬虫将它们的服务器搞过载 或者 搞垮,会设有反爬虫机制。反爬虫机制就是:将一些用户代理 封禁,禁止一些 用户代理 访问他们的服务器。
比如这个例子:在我们使用urllib2 默认的用户代理 ( Python-urllib/2.7 ) 来 http://www.meetup.com/ 网站,你会看到下面的访问拒绝提示:
>>> html = download('http://blog.csdn.net/github_35160620/article/details/52487618')
Downloading: http://blog.csdn.net/github_35160620/article/details/52487618
Download error Forbidden
>>> html = download('http://www.meetup.com/')
Downloading: http://www.meetup.com/
Download error Forbidden
>>>
所以,如果我们能过将网络爬虫 的 用户代理 设置为 浏览器的用户代理,该多好啊。这样我们的网络爬虫就可以让服务器误以为:是一个浏览器在访问它。
下面这个图,就是 Chrome 浏览器的 用户代理 (user_agent)。
这是完全可以实现的,下面我们将来介绍,如何设定。
现在修改 download() 函数,将用户代理 设定为:wswp 这个字符串。(即 Web Scraping with Python 的首字母缩写。)
import urllib2
def download(url, user_agent='wswp', num_retries=2):
print 'Downloading: ', url
headers = {'User-agent' : user_agent}
request = urllib2.Request(url, headers=headers)
try:
html = urllib2.urlopen(request).read()
except urllib2.URLError as e:
print 'Download error', e.reason
html = None
if num_retries > 0:
if hasattr(e, 'code') and 500 <= e.code < 600:
# recursively retry 5xx HTTP errors
return download(url, user_agent, num_retries-1)
return html
运行:
>>> html = download('http://www.meetup.com/')
Downloading: http://www.meetup.com/
通过运行结果,你也看到了:通过设置了自定义的用户代理(user_agent)后,一些反爬虫的网站有可以下载了。现在,这个 download() 就是一个灵活的下载程序,该函数能够捕获异常,并且可以自动尝试重新下载,并且我们设置了自定义的用户代理(user_agent)。
搞定
下一节,我们来解决乱码问题
如果我们下载一个带有中文的网站,或者日文的网站,终止就是不全是英文的网站。我们将这个网站下载下来后,将它输出,会有乱码。
举例:
>>> html = download('http://blog.csdn.net/github_35160620/article/details/52487618')
Downloading: http://blog.csdn.net/github_35160620/article/details/52487618
>>> print html
...
...
...
</div>
<!-- 骞垮憡浣嶅紑濮?-->
<ins data-revive-zoneid="72" data-revive-id="8c38e720de1c90a6f6ff52f3f89c4d57"></ins>
<!-- 骞垮憡浣嶇粨鏉?-->
<link rel="stylesheet" href="http://static.blog.csdn.net/css/blog_code.css" />
<script type="text/javascript" src="http://static.blog.csdn.net/scripts/saveToCode.js"></script>
...
...
...
下一节,就来解决这个问题。
总结:
这一节,我们已经 网络爬虫程序的下载网页的部分搞定了。下一节,我们来解决乱码问题。
Python 网络爬虫 005 (编程) 如何编写一个可以 下载(或叫:爬取)一个网页 的网络爬虫的更多相关文章
- Python 网络爬虫 004 (编程) 如何编写一个网络爬虫,来下载(或叫:爬取)一个站点里的所有网页
爬取目标站点里所有的网页 使用的系统:Windows 10 64位 Python语言版本:Python 3.5.0 V 使用的编程Python的集成开发环境:PyCharm 2016 04 一 . 首 ...
- 【python爬虫】对喜马拉雅上一个专辑的音频进行爬取并保存到本地
>>>内容基本框架: 1.爬虫目的 2.爬取过程 3.代码实现 4.爬取结果 >>>实验环境: python3.6版本,pycharm,电脑可上网. [一 爬虫目 ...
- Python爬虫入门教程 13-100 斗图啦表情包多线程爬取
斗图啦表情包多线程爬取-写在前面 今天在CSDN博客,发现好多人写爬虫都在爬取一个叫做斗图啦的网站,里面很多表情包,然后瞅了瞅,各种实现方式都有,今天我给你实现一个多线程版本的.关键技术点 aioht ...
- 爬虫入门之Scrapy框架基础框架结构及腾讯爬取(十)
Scrapy终端是一个交互终端,我们可以在未启动spider的情况下尝试及调试代码,也可以用来测试XPath或CSS表达式,查看他们的工作方式,方便我们爬取的网页中提取的数据. 如果安装了 IPyth ...
- Python:将爬取的网页数据写入Excel文件中
Python:将爬取的网页数据写入Excel文件中 通过网络爬虫爬取信息后,我们一般是将内容存入txt文件或者数据库中,也可以写入Excel文件中,这里介绍关于使用Excel文件保存爬取到的网页数据的 ...
- 爬虫系列4:scrapy技术进阶之多页面爬取
多页面爬取有两种形式. 1)从某一个或者多个主页中获取多个子页面的url列表,parse()函数依次爬取列表中的各个子页面. 2)从递归爬取,这个相对简单.在scrapy中只要定义好初始页面以及爬虫规 ...
- 使用htmlparse爬虫技术爬取电影网页的全部下载链接
昨天,我们利用webcollector爬虫技术爬取了网易云音乐17万多首歌曲,而且还包括付费的在内,如果时间允许的话,可以获取更多的音乐下来,当然,也有小伙伴留言说这样会降低国人的知识产权保护意识,诚 ...
- 使用htmlparser爬虫技术爬取电影网页的全部下载链接
昨天,我们利用webcollector爬虫技术爬取了网易云音乐17万多首歌曲,而且还包括付费的在内,如果时间允许的话,可以获取更多的音乐下来,当然,也有小伙伴留言说这样会降低国人的知识产权保护意识,诚 ...
- Python 爬取单个网页所需要加载的地址和CSS、JS文件地址
Python 爬取单个网页所需要加载的URL地址和CSS.JS文件地址 通过学习Python爬虫,知道根据正式表达式匹配查找到所需要的内容(标题.图片.文章等等).而我从测试的角度去使用Python爬 ...
随机推荐
- mysql ORM框架及SQLAlchemy
一 介绍 SQLAlchemy是Python编程语言下的一款ORM框架,该框架建立在数据库API之上,使用关系对象映射进行数据库操作,简言之便是:将对象转换成SQL,然后使用数据API执行SQL并获取 ...
- hdoj-1032-The 3n + 1 problem(坑题)
题目链接 //巨坑的一道题,输入的m,n要判断大小,输出还要按照原来的顺序,范围还是i<=n<=j #include <iostream> #include <cstd ...
- python any函数
pyhton的any() 函数: 判断给定的可迭代参数 iterable : 全部为 False,返回 False; 至少有一个为 True,则返回 True. 元素除了是 0.空.FALSE 外都算 ...
- UVA - 1610 Party Games (字符串比较)
给你n(n为偶数)个字符串,让你找出一个长度最短且字典序尽量小的字符串,使得一半的字符串小于等于该串,一半的字符串大于该串. 紫薯上说这道题有坑,但其实思路对了就没什么坑. 很明显,只要取夹在中间两个 ...
- Balanced Lineup(线段树的简单了解)
个人心得:线段树就是将一段序列拆分为一个个单独的节点,不过每俩个节点又可以联系在一起,所以就能很好的结合,比如这一题, 每次插入的时候都将这一段区间的最大最小值更新,就能大大减少时间. 这个线段树建立 ...
- 「新手向」koa2从起步到填坑
前传 出于兴趣最近开始研究koa2,由于之前有过一些express经验,以为koa还是很好上手的,但是用起来发现还是有些地方容易懵逼,因此整理此文,希望能够帮助到一些新人. 如果你不懂javascri ...
- SpringCloud微服务实战——第三章服务治理
Spring Cloud Eureka 服务治理 是微服务架构中最核心最基本的模块.用于实现各个微服务实例的自动化注册与发现. 服务注册: 在服务治理框架中,都会构建一个注册中心,每个服务单元向注册中 ...
- TIJ摘要:访问控制权限
重构的原动力之一:发现有更好的方式去实现相同的功能. OOP需要考虑的基本问题:如何把变动的事物与不变的事物区分开来. 访问控制权限:以供类库开发人员向客户端程序员指明哪些是可用的,哪些是不可用的.访 ...
- Makefile 自动产生依赖 ***
代码如下: 其实这里主要是为每个C文件建立一个同名的后缀为.d.该文件的作用是使用gcc的-M属性来自动生成.o文件的头文件依赖关系. 第1,2,4都好理解. 第2行解释: 使用gcc -M 的属性将 ...
- 在Azure New Portal上创建基于ARM的带SLB的VM
目前Azure的New Portal在国内已经上线了.本文将介绍最常见的一种场景:通过Azure的New Portal创建带有Server Load Balance的多台虚拟机. 1 创建Resour ...