《Python网络数据采集》读书笔记(一)

思考“网络爬虫”时通常的想法:

? 通过网站域名获取 HTML 数据

? 根据目标信息解析数据

? 存储目标信息

? 如果有必要,移动到另一个网页重复这个过程

当网络浏览器遇到一个标签时,比如<img src="cuteKitten.jpg">,会向服务器发起另一个请求,以获取cuteKitten.jpg文件中的数据为用户充分渲染网页。但是,我们的Python程序没有返回并向服务器请求多个文件的逻辑,它只能读取我们已经请求的单个HTML文件。

1、初识urllib库

urllib是标准库,在 Python 3.x 里,urllib2 改名为 urllib,被分成一些子模块:urllib.request 、urllib.parse和urllib.error。

urlopen 用来打开并读取一个从网络获取的远程对象。

导入urlopen ,然后调用 html.read() 获取网页的HTML内容。

>>> from urllib.request import urlopen
>>> html = urlopen("http://pythonscraping.com/pages/page1.html")
>>> print(html.read())
b'<html>\n<head>\n<title>A Useful Page</title>\n</head>\n<body>\n<h1>An Interesting Title</h1>\n<div>\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n</div>\n</body>\n</html>\n'

2、使用虚拟环境

可以用虚拟环境保存库文件。

如下:创建了一个叫作scrapingEnv的新环境,然后激活它;在新建的scrapingEnv环境里,可以安装并使用BeautifulSoup;最后通过释放命令来退出环境。

$ virtualenv scrapingEnv

$ cd scrapingEnv/
$ source bin/activate

(scrapingEnv)ryan$ pip install beautifulsoup4
(scrapingEnv)ryan$ python
> from bs4 import BeautifulSoup
>

(scrapingEnv)ryan$ deactivate
$

可以使用如下任意一命令安装BeautifulSoup库

pip3 install bs4
pip3 install beautifulsoup4

3、初识BeautifulSoup库

把HTML内容传到BeautifulSoup对象(html.parser是内置的解析器),从网页中提取的 <h1> 标签被嵌在 BeautifulSoup 对象 bsObj 结构的第二层(html → body → h1)

>>> from urllib.request import urlopen
>>> from bs4 import BeautifulSoup
>>> html = urlopen("http://pythonscraping.com/pages/page1.html")
>>> bsObj = BeautifulSoup(html.read(), 'html.parser')
>>> print(bsObj.h1)
<h1>An Interesting Title</h1>

*下面的所有函数调用都可以产生同样的结果:

bsObj.h1

bsObj.html.body.h1

bsObj.body.h1

bsObj.html.h1

4、处理异常

网页在服务器上不存在(或者获取页面的时候出现错误), urlopen函数会抛出“HTTPError”异常。

如果服务器不存在(就是说链接打不开,或者是URL链接写错了),urlopen会返回一个None对象。

用以下方式处理:

try:
    html = urlopen("http://pythonscraping.com/pages/page1.html")
except HTTPError as e:
    print(e)
    # 中断程序,或者执行另一个方案
else:
    if html is None:
        print("URL is not found")
    else:
        # 程序继续
        pass

调用BeautifulSoup对象里的一个标签不存在会返回None对象。

再调用这个None对象下面的子标签,就会发生 AttributeError错误。

用以下方式处理:

try:
    bsObj = BeautifulSoup(html.read(), 'html.parser')
    badContent = bsObj.body.h2
except AttributeError as e:
    print("Tag was not found")
else:
    if badContent == None:
        print("Tag was not found")
    else:
        print(badContent)

5、重新整理组织以上代码

# -*- coding: utf-8 -*-
from urllib.request import urlopen
from urllib.error import HTTPError
from bs4 import BeautifulSoup

def getTitle(url):

    try:
        html = urlopen(url)        
    except HTTPError as e:
        return None
    try:
        bsObj = BeautifulSoup(html.read(), 'html.parser')
        title = bsObj.body.h1
    except AttributeError as e:
        return None
    return title
    
    
title = getTitle("http://pythonscraping.com/pages/page1.html")
if title == None:
    print("Title could not be found")
else:
    print(title)

我们创建了一个getTitle函数,用于返回网页的标题。如果获取网页的时候遇到问题就返回一个None对象。

在getTitle函数里面,我们像前面那样检查了HTTPError ,然后把两行BeautifulSoup代码封装在一个try语句里面。这两行中的任何一行有问题,AttributeError都可能被抛出(如果服务器不存在, html 就是一个None对象,html.read() 就会抛出 AttributeError )。

原文地址:http://blog.51cto.com/9473774/2092235

时间: 2024-10-06 15:56:26

《Python网络数据采集》读书笔记(一)的相关文章

高性能javascript读书笔记(三.DOM 编程1)

第三章DOM Script DOM编程 读书笔记 访问和修改DOM元素 浏览器通常要求DOM实现和JavaScript保持相互独立. <!-- 例如IE中,被称为JScript的JavaScript实现位于库文件jscript.dll中,而DOM实现位于另一个库mshtml.dll(内 部代号Trident).这种分离技术允许其他技术和语言,如VBScript,受益于Trident所提供的DOM功能和渲染功能.Safari使用Webkit的WebCore处理DOM和渲染,具有一个分离的JavaS

数据访问---高性能JavaScript读书笔记(2)

对于任何一种编程语言来说,数据存储的位置关系到访问速度! 在JavaScript中的直接量包括字符串string.数字number.布尔值boolean.对象object.数组array.函数function.正则表达式regular expression.空值null.未定义数组undefined.而数组项则需要通过数组的数字索引来访问,对象通过字符串进行索引来访问其成员(这里顺便提一句因为数组项是通过数字进行索引.对象成员是通过字符串进行索引,所以这也就是为什么访问对象成员比访问数组项更慢的

加载和运行---高性能JavaScript读书笔记(1)

众所周知大多数浏览器是使用单进程处理UI更新和JavaScript运行等多个任务的,而同一时间只能有一个任务被执行,如此说来,JavaScript运行了多长时间就意味着用户得等待浏览器响应需要花多久时间. 从认知上来说,解析器解析一个界面的时候都是从上至下依次解析的,这就是说界面上出现多少个<script>标签(不管是内联还是外部文件),页面下载和解析必须停止等待脚本下载完成并运行完成(注意这里包括运行),这个过程当中,页面解析和用户交互是被完全阻塞的. Javascript第一条定律:将脚本

DOM访问---高性能JavaScript读书笔记(3)

在JavaScript高级程序设计第一章当中就把JavaScript分成三大部分 所以事实上DOM和BOM是两在独立的部分,它们之间的通信是通过相互之间的功能接口来实现的,这样说来两个独立的部分以功能接口必定会带来性能损耗.这也就是为什么大家一致都说尽量少去访问和修改DOM元素(注意我这里说的是访问和修改,为什么包括访问,请继续往下看  哈哈). 下面用一张图来说明它们各自的作用. 1.在修改DOM元素的时候,我们应该尽量使用innerHTML而不是CreateElement再AppendChi

高性能javascript读书笔记(三.DOM 编程2)

重绘和重排版 浏览器下载完所有的HTML标记,Javascript,CSS,图片之后,它解析文件并创建两个内部数据结构 DOM树 表示页面结构渲染树 表示DOM节点如何显示 渲染树中为每个需要显示的DOM树木=节点存放至少一个节点(隐藏DOM元素在选桉树中没有对应节点)渲染树上的节点称为"框"或者"盒",符合CSS模型的定义,将页面元素看作一个具有填充,边距,边框和位置的盒.一 旦DOM树和渲染树构造完毕,浏览器就可以显示(绘制)页面上的元素了. 当DOM改变影响到

Javascript读书笔记:函数定义和函数调用

定义函数 使用function关键字来定义函数,分为两种形式: 声明式函数定义: function add(m,n) { alert(m+n); } 这种方式等同于构造一个Function类的实例的方式: var add = new Function("m", "n", "alert(m+n);"); Function类构造方法的最后一个参数为函数体:"alert(m+n);",前面的都是函数的形参,参数必须是字符串形式的:&

Javascript读书笔记:字符串常用方法

concat() 连接多个字符串,返回合并后的字符串. 1 var s1="a"; 2 var s2="b"; 3 var s3="c"; 4 5 console.log(s1.concat(s2,s3));//abc 数组中的concat():将参数添加为数组的元素,返回新的数组. 1 var arr = [1, 2, 3]; 2 console.log(arr.concat(4, 5));//[1,2,3,4,5] indexOf() 查找子

高性能javascript学习笔记系列(1) -js的加载和执行

这篇笔记的内容主要涉及js的脚本位置,如何加载js脚本和脚本文件执行的问题,按照自己的理解结合高性能JavaScript整理出来的 javascript是解释性代码,解释性代码需要经历转化成计算机指令的过程,这个过程就会带来一定的性能损耗,所以在js中做性能的优化是必须的 javascript的阻塞特性:浏览器在执行js代码的时候,不能做其他的任何事情,因为浏览器使用单一的进程来处理用户界面的刷新和javascript的脚本执行,也就是说什么时候执行js脚本影响着用户对页面的使用体验(之所以js

高性能javascript学习笔记系列(6) -ajax

参考 高性能javascript javascript高级程序设计 ajax基础  ajax技术的核心是XMLHttpRequest对象(XHR),通过XHR我们就可以实现无需刷新页面就能从服务器端读取数据 var xhr = new XMLHttpRequest(); //只支持IE7以及更高的版本 xhr.onreadystatechange = function() { if(xhr.readyState == 4) { if( (xhr.status >= 200 && xh

高性能javascript学习笔记系列(5) -快速响应的用户界面

参考高性能javascript 理解浏览器UI线程  用于执行javascript和更新用户界面的进程通常被称为浏览器UI线程  UI线程的工作机制可以理解为一个简单的队列系统,队列中的任务按顺序执行 <button onclick="handleClick()">click</button> <script type="text/javascript"> function handleClick() { var div = do