Python网络数据采集(爬虫)

原书链接:https://pan.baidu.com/s/1eTSi3FO 密码:9uy1

 

写代码之前拟个大纲或画个流程图是很好的编程习惯,这么做不仅可以为你后期处理节省 很多时间,更重要的是可以防止自己在爬虫变得越来越复杂时乱了分寸。(自己当产品经理)

添加处理异常会让代码更好体验在写爬虫的时候,思考代码的总体格局,让代码既可以捕捉异常又容易阅读,这是很重要 的。如果你还希望能够很大程度地重用代码,那么拥有像 getSiteHTML 和 getTitle 这样的 通用函数(具有周密的异常处理功能)会让快速稳定地网络数据采集变得简单易行。

豆瓣目录   

如果你想入门爬虫,推荐这本书,此书使用的是Py3.

第一,二章直接推荐大家使用BeautifulSoup来解析网页,个人觉得最好用的还是lxml,但是本书并没有讲到。BS的使用分为三个步骤,创建,搜索,访问。直接引用标签只会返回第一个匹配的element,你如果想要返回多个那么就要使用find_all,如果限制访问个数择则有一个limit属性,如果访问标签不存在则会返回None,但是如果继续访问这个不存在标签的属性,则会返回Error,所以使用要注意。其他的使用还有很多,例如Navigating Trees,BS最最强大的在于它支持ReEx,还有很多小的细节,访问节点的三种方式,匿名函数,最后也推荐了lxml。个人提示,当你的电脑装了lxml之后,在使用Bs创建对象的时候,加上html的解析器属性--html.parser
第三章,爬虫的基础,算是前面讲解的实战。
第四章,使用API爬取信息,可以省略大部分,后面关于JSON的解析有必要注意一下,loads,jumps直接对于Json格式和字典的转换。
第五章,存储数据,介绍了CSV(comma-separated values),以及MySQL,MySQL的使用可以专门去学习,而且很重要。Py2中是用MySQLdb库来操作数据库,在Py3中则换用PyMySQL,最后则是讲解了使用smtplib来发送Email,因人而异的功能。
第六章,文本的操作,手先讲解了编码的处理,decode > unicode > encode,utf8只是unicode的编码实现方式。首先是如何处理CSV文件(CSV),然后PDF(pdfminer)及docx(zipfile)
第七章,高阶爬虫的技巧,也是我看本书的最终目的。本章着重讲解数据的清洗,使用正则,或者repalce一下,其实python的numpy或者pandas在这方面已经很优秀。同时本书介绍了专门的软件按OpenRefine.
第八章,马尔可夫模型生成伪随机文本,还介绍了NLTK工具包,这个英文支持良好,中文不了解。
第九章,模拟登录,使用强大的requests。保持登录使用session来访问,最后稍微讲解了Auth。
第十章,Js解析,使用selenium和PhantomJS来解析网页,通过调用API来实现一些操作,最后处理了客户端Js重定向问题,服务器端不用担心,因为Python的内置库文件自动执行
第十一章,图像识别,反爬虫机制的发展是不断上升的过程。在CAPTCHAs可以使用PIL简单识别,或者使用Tesseract来模拟训练,图像识别或者说OCR本身就是很大的方向,可忽略
第十二章,避免爬虫陷阱,介绍一些坑爹的页面反爬虫机制及处理方式
第十三章,测试技巧,使用unittest或selenium测试
第十四章,IP限制使用Tor,但是国内被墙制作了解,及使用Google或者AWS的云服务
下面需要看一下算法或者深入机器学习的书籍,数据的获取和处理,我想作为一个数学系的学生,重点是如何Learning,如何去特征提取,Python的编程只是加分项,我也只把Python作为唯一的编程工具,源码需要学习。

第一部分 创建爬虫 

 采集信息用的程序一般被称为网络爬虫(Web crawler)、网络铲(Web scraper,可类比考古用的洛阳铲)、网络蜘蛛(Webspider),其行为一般是先“爬”到对应的网页上,再把需要的信息“铲”下来。网络数据采集程序也像是一只辛勤采蜜的小蜜蜂,它飞到花(目标网页)上,采集花粉(需要的信息),经过处理(数据清洗、存储)变成蜂蜜(可用的数据)。

思考“网络爬虫”时通常的想法:(就是自己写api)
 • 通过网站域名获取HTML 数据
 • 根据目标信息解析数据
 • 存储目标信息
 • 如果有必要,移动到另一个网页重复这个过程

用虚拟环境保存库文件
    如果同时负责多个 Python 项目,或者想要轻松打包某个项目及其关联的库文件,再 或者你担心已安装的库之间可能有冲突,那么你可以安装一个 Python 虚拟环境来分而 治之。(大事化小)

    将项目关联的所有库单独放在一个虚拟环境里,还可以轻松打包整个环境发生给其他 人。只要他们的 Python 版本和你的相同,你打包的代码就可以直接通过虚拟环境运 行,不需要再安装任何库。

urlopen 用来打开并读取一个从网络获取的远程对象。因为它是一个非常通用的库(它可以轻松读取 HTML 文件、图像文件,或其他任何文件流)。

异常检测:

from urllib.request import urlopen
from urllib.error import HTTPError
from bs4 import BeautifulSoup
import sys

def getTitle(url):
    try:
        html = urlopen(url)
    except HTTPError as e:
        print(e)
        return None
    try:
        bsObj = BeautifulSoup(html.read())
        title = bsObj.body.h1
    except AttributeError as e:
        return None
    return title

title = getTitle("http://www.pythonscraping.com/exercises/exercise1.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)。其实,我们可以在try 语句里面放任意多行代码,或者放一个在任意位置都可以抛出AttributeError 的函数。

 

复杂HTML解析

在面对埋藏很深或格式不友好的数据时,千万不要不经思考就写代码,一定要三思 而后行。(手机端、、、)
 

BeautifulSoup强大过滤能力  假如你正在处理一个包含许多超链接、段落和标签的大段源代码,那么.get_text() 会把这些超链接、段落和标签都清除掉,只剩下一串不带标签的文字。通常在你准备打印、存储和操作数据时,应该最后才使用.get_text()。一般情况下,你应该尽可能地保留HTML 文档的标签结构。数组转为对象

.findAll({"h1","h2","h3","h4","h5","h6"})

.findAll("span", {"class":{"green", "red"}})

nameList = bsObj.findAll("span", {"class":"green"})
           
下面两行代码是完全一样的:
bsObj.findAll(id="text") 
bsObj.findAll("", {"id":"text"})

返回的列表

选择器强大,类似css选择器,兄弟,后代(导航树)

 

  • 因为class 是Python 中受保护的关键字。也就是说,class 是Python 语言的保留字,在Python 程序里是不能当作变量或参数名使用的(和前面介绍的BeautifulSoup.findAll() 里的keyword 无关)另外,你也可以用属性参数把class 用引号包起来:
    bsObj.findAll("", {"class":"green"})

正则:

from urllib.request import urlopen
from bs4 import BeautifulSoup
import re, requests

html = urlopen("http://www.pythonscraping.com/pages/page3.html")
bsObj = BeautifulSoup(html, "html.parser")
images = bsObj.findAll("img", {"src":re.compile("\.\.\/img\/gifts/img.*\.jpg")})
for image in images: 
    print(image["src"])

 Lambda 表达式,下面的代码就是获取有两个属性的标签:
 soup.findAll(lambda tag: len(tag.attrs) == 2)
这行代码会找出下面的标签:
 <div class="body" id="content"></div>
 <span style="color:red" class="title"></span>
如果你愿意多写一点儿代码,那么在BeautifulSoup 里用Lambda 表达式选择标签,将是正则表达式的完美替代方案。


遍历数组可以直接tag[3],直接数组下标取值。

 

BeautifulSoup 对象查找你想要的信息,比直接在 HTML 文本里查找信 息要简单得多。通常在你准备打印、存储和操作数据时,应该最后才使 用 .get_text()。一般情况下,你应该尽可能地保留 HTML 文档的标签结构。               bs4结合正则更厉害哦

 

重定向(redirect)允许一个网页在不同的域名下显示。重定向有两种形式:

1 、服务器端重定向,网页在加载之前先改变了 URL; 

2 、客户端重定向,有时你会在网页上看到“10 秒钟后页面自动跳转到……”之类的消息, 表示在跳转到新 URL 之前网页需要加载内容。

 

开始采集

对获取链接多观察,寻找最好方法!

Scrapy 就是一个帮你大幅度降低网页链接查找和识别工作复杂度的 Python 库,它可以让你轻松地采集一个或多个域名的信息。不过目前 Scrapy 仅支持 Python 2.7,还不支持Python 3.x。

使用API(和其他网站结合,调用数据)

    究竟 API 和普通的网址访问有什么区别呢?如果不考虑 API 高大上的名称,其实两者没啥区别。API 可以通过 HTTP 协议下载文件,和 URL 访问网站获取数据的协议一样,它几乎可以实现所有在网上干的事情。API 之所以叫 API 而不是叫网站的原因,其实

是首先 API 请求使用非常严谨的语法,其次 API 用 JSON 或 XML 格式表示数据,而不是HTML 格式。

输入ip看国家:

import json
from urllib.request import urlopen

def getCountry(ipAddress):
    response = urlopen("http://freegeoip.net/json/"+ipAddress).read().decode('utf-8')
    responseJson = json.loads(response)
    return responseJson.get("country_code")
print(getCountry("50.78.253.58"))

存储数据

媒体文件
存储媒体文件有两种主要的方式:只获取文件URL 链接,或者直接把源文件下载下来

 

把数据存储到CSV
CSV(Comma-Separated Values,逗号分隔值)是存储表格数据的常用文件格式。Microsoft
Excel 和很多应用都支持CSV 格式,因为它很简洁。下面就是一个CSV 文件的例子:
fruit,cost
apple,1.00

MySQL(Navicat for MySQL神器)

“关系型数据”就是有关联的数据。就是这么简单!

 

每个字段定义由三部分组成:
• 名称( id 、 title 、 created 等)
• 数据类型( BIGINT(7) 、 VARCHAR 、 TIMESTAMP )
• 其他可选属性( NOT NULL AUTO_INCREMENT )

有一些技巧你其实可以很快地学会,它们可以让你的数据库变得更高效:

  1. 给每个数据表都增加一个 id 字段
  2. 用智能索引。字典(指的是常用的工具书,不是指 Python 的字典对象)是按照字母顺序排列的单词表
  3. 最后一点是关于数据查询时间和数据库空间的问题。一个常见的误区就是在数据库中存储大量重复数据,尤其是在做大量自然语言数据的网络数据采集任务时。如果把这些数据分成三个表,你就可以看到数据库占用的空间会大大降低,虽然表定义的结构变复杂了,但是新增的字段就是 id 字段。它们是整数,不会占用很多空间。另外,每个 URL 和词组都只会储存一次。(大块化小,id占内存小

读取文档

txt    csv    pdf    word

高级数据采集

你将掌握如何用网络爬虫测试网站,自动化处理,以及通过更多的方式接入网络。最后你将学到一些数据采集的工具,帮助你在不同的环境中收集和操作任意类型的网络数据,深入互联网的每个角落。

数据清洗

高级数据采集
def ngrams(input, n):
content = re.sub('\n+', " ", content)
content = re.sub(' +', " ", content)
content = bytes(content, "UTF-8")
content = content.decode("ascii", "ignore")
print(content)
input = input.split(' ')
output = []
for i in range(len(input)-n+1):
output.append(input[i:i+n])
return output
这里首先把内容中的换行符(或者多个换行符)替换成空格,然后把连续的多个空格替换成一个空格,确保所有单词之间只有一个空格。最后,把内容转换成 UTF-8 格式以消除转义字符。

 

自然语言处理

穿越网页表单与登录窗口进行采集

Requests 库(http://www.python-requests.org/)就是这样一个擅长处理那些复杂的HTTP 请
求、cookie、header(响应头和请求头)等内容的Python 第三方库。

采集JavaScript

图像识别与文字处理

 

避开采集陷阱

远程采集

 

《Python之禅》 Tim Peters

优美胜于丑陋

明了胜于隐晦

简洁胜于复杂

复杂胜于混乱

扁平胜于嵌套

宽松胜于紧凑

可读性很重要

即便是特例,也不可违背这些规则

虽然现实往往不那么完美

但是不应该放过任何异常

除非你确定需要如此

如果存在多种可能,不要猜测

肯定有一种——通常也是唯一一种——最佳的解决方案

虽然这并不容易,因为你不是Python之父1

动手比不动手要好

但不假思索就动手还不如不做

如果你的方案很难懂,那肯定不是一个好方案

如果你的方案很好懂,那肯定是一个好方案

命名空间非常有用,我们应当多加利用

 

 

展开阅读全文

没有更多推荐了,返回首页