欢迎来到吾爱文库! | 帮助中心 分享价值,成长自我!
吾爱文库
全部分类
  • 商业/管理/HR >
    商业/管理/HR
    商业计划书 创业/孵化 市场营销 经营企划 销售管理 营销创新 宣传企划 资本运营 代理连锁/招商加盟 商业合同/协议 公司方案 企业信息化/信息管 管理学资料 企业文档 广告经营 财务报表 项目/工程管理 物业管理 质量控制/管理 企业文化 绩效管理 商务礼仪 励志书籍/材料 人事档案/员工关系 薪酬管理 招聘面试 咨询培训 劳动就业 劳务/用工合同 其它文档
  • 办公文档 >
    办公文档
    PPT模板库 总结/报告 演讲稿/致辞 心得体会 工作范文 述职报告 工作计划 解决方案 调研报告事务文书 经验/事迹 往来文书 模板/表格 规章制度 教学/培训 通知/申请 求职简历 理论文章 统计图表礼仪/庆典 活动策划 会议纪要 招标投标 其它办公文档
  • 高等教育 >
    高等教育
    大学课件 研究生课件 工学 理学 习题/试题 历史学 农学 教育学 哲学 科普读物 政治/理论 专业基础教材 生物学 语言学 微积分 统计学 实验设计 其它相关文档
  • 中学教育 >
    中学教育
    教学课件 高考 中考 高中教育 初中教育 职业教育 中学学案 中学作文 中学实验 高考英语 试题/考题 竞赛题 教学研究 体育理论与教学 音乐美术 视频课件/素材 其它中学文档
  • 医学/心理学 >
    医学/心理学
    基础医学 药学 中医/养生 医学研究方法 心理学理论/研究方 医学试题/课件 心理学论文 心理咨询与治疗 医学现状与发展 心理学书籍 外科学 内科学 妇产科学 神经内外科 烧伤科 眼科学 口腔科学 皮肤病学/性病学 耳鼻咽喉科学 神经病/精神病学 肿瘤学 儿科学 骨科学 康复医学 麻醉学 护理学 检验医学 针灸学 预防医学/卫生学 重症医学 病毒学 外国及民族医学 特种医学 心理健康教育 医学影像 兽医 偏方 综合/其它
  • 资格认证/考试 >
    资格认证/考试
    公务员考试 专升本考试 建造师考试 教师资格考试 全国翻译资格认证 成考 自考 司法考试 微软认证 网络工程师认证 注册会计师 医师/药师资格考试 会计职称考试 报关员资格考试 人力资源管理师 安全工程师考试 出国培训 资产评估师考试 技工职业技能考试 银行/金融从业资格 计算机等级考试 营养师认证 物流师考试 证券从业资格考试 注册税务师 理财规划师 建筑师考试 质量管理体系认证 其它考试类文档
  • 行业资料 >
    行业资料
    食品饮料 化学工业 展会/博览会 国内外标准规范 造纸印刷 纺织服装 家居行业 酒店餐饮 物流与供应链 室内设计 工业设计 家电行业 生活/日用品 航海/船舶 水产/渔业 传媒/媒体 公共安全/评价 畜牧/养殖 林业/苗木 园艺/花卉 农作物 轻工业/手工业 教育/培训 零售业 水利工程 农业工程 系统集成 冶金工业 金属学与工艺 社会学 武器工业 能源与动力工程 原子能技术 文化创意 航空/航天 石油/天然气工业 矿业工程 交通运输 旅游娱乐 实验/测试 其它行业文档
  • 经济/贸易/财会 >
    经济/贸易/财会
    经济学 资产评估/会计 贸易 市场分析 网络营销/经济 商品学 进出口许可 财政/国家财政 税收 稽查与征管/审计 综合/其它
  • 电子/通信 >
    电子/通信
    电子设计/PCB 电子电气自动化 数据通信与网络 光网络传输 无线电电子学/电信 网规网优 核心网技术 运营商及厂商资料 WiMAX技术 TD-SCDMA技术 3G/4G及新技术 CDMA95/CDMA2000/EV WCDMA技术 GSM/GPRS/EDGE 天线/微波/雷达 监控/监视 室内分布 视频会议 考试/面试试题 综合/其它
  • 生活休闲 >
    生活休闲
    服装配饰 美食烹饪 户外/运动 摄影摄像 家居装修 娱乐/时尚 保健/养生 两性/情感 时政新闻 科普知识 社会民生 星座/运势/宗教/风 美容/塑身 婚嫁/育 琴棋书画 游戏攻略 期刊/杂志 留学/签证 手工制作 滑稽幽默 网络生活 武术 彩票 宠物 充电交流 综合/其它
  • IT计算机/网络 >
    IT计算机/网络
    计算机应用/办公自 .NET 数据结构与算法 Java SEO/搜索引擎优化 C/C++资料 linux/Unix相关 手机/mobile开发 UML理论/建模 云计算/并行计算 嵌入式开发/单片机 Windows相关 软件工程 管理信息系统 开发文档 图形图像 网络与通信 网络安全 电子支付 Labview matlab 网络资源 Python Delphi/Per 评测 Flash/Flex CSS/Scr 计算机原理 PHP资料 数据挖掘与识别 Web服务 数据库 VisualBasic 电子商务 服务器 存储 架构 行业软件 人工智能 计算机辅助设计 多媒体应用 软件测试 计算机硬件与维护 网站策划/UE 网页设计/UI 网吧管理 其它相关文档
  • 研究报告 >
    研究报告
    信息产业 农林牧渔 统计年鉴/数据分析 商业贸易 产业政策 石油化工 金融 教育 冶金 轻工 交通 制药行业 安防行业 煤炭 新能源 国防军事 技术指导 综合/其它
  • 换一换
    首页 吾爱文库 > 资源分类 > PDF文档下载
     

    Python网络数据采集.pdf

    • 资源ID:13710       资源大小:17.78MB        全文页数:222页
    • 资源格式: PDF        下载权限:游客/注册会员/VIP会员    下载费用:50金币 【人民币50元】
    快捷注册下载 游客一键下载
    会员登录下载
    三方登录下载: QQ登录   微博登录  
    下载资源需要50金币 【人民币50元】
    邮箱/手机:
    温馨提示:
    支付成功后,系统会自动生成账号(用户名和密码都是您填写的邮箱或者手机号),方便下次登录下载和查询订单;
    支付方式: 微信支付    支付宝   
    验证码:   换一换

    加入VIP,下载共享资源
     
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,既可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰   

    Python网络数据采集.pdf

    m 2 u0 €  Z   ] V[ i  1 - „1 › b Œ ] ™0 € ] P  q ƒ‚›.lb  iM€ ƒ“  „   ]  M ƒb T ™€ S ƒ› V  L  “Œ‚K1 k| ƒn i V E p 3 b f M 图灵程序设计丛书 人 民 邮 电 出 版 社 北 京 Web Scraping with Python Collecting Data from the Modern Web [美 ] Ryan Mitchell 著 陶俊杰 陈小莉 译 Python 网络数据采集 Beijing Cambridge Farnham Kln Sebastopol Tokyo O’Reilly Media, Inc.授权人民邮电出版社出版 内 容 提 要 本书采用简洁强大的Python语言,介绍了网络数据采集,并为采集新式网络中的各种数据类 型提供了全面的指导。第一部分重点介绍网络数据采集的基本原理如何用Python从网络服务器 请求信息,如何对服务器的响应进行基本处理,以及如何以自动化手段与网站进行交互。第二部 分介绍如何用网络爬虫测试网站,自动化处理,以及如何通过更多的方式接入网络。 本书适合需要采集Web数据的相关软件开发人员和研究人员阅读。 定价59.00元 读者服务热线01051095186转 600 印装质量热线01081055316 反盗版热线01081055315 广告经营许可证京崇工商广字第 0021 号 著 [美] Ryan Mitchell 译 陶俊杰 陈小莉 责任编辑 岳新欣 执行编辑 李 敏 责任印制 杨林杰 人民邮电出版社出版发行 北京市丰台区成寿寺路11号 邮编 100164 电子邮件 315 网址 北京 印刷 开本8001000 1/16 印张13.5 字数280千字 2016年 3 月第 1 版 印数1 4 000册 2016年 3 月北京第 1次印刷 著作权合同登记号 图字01-2015-8108号 ◆ ◆ ◆ iii 版权声明 2015 by Ryan Mitchell. Simplified Chinese Edition, jointly published by O’Reilly Media, Inc. and Posts 因为每个MySQL实例可以有多个数据库,所以使用某个数据库之前需要指定数据库的 名称 USE scraping; 从现在开始(直到关闭MySQL链接或切换到另一个数据库之前),所有的命令都运行在这 个新的“scraping”数据库里面。 所有操作看着都非常简单。那么,在数据库里创建数据表的方法应该也类似吧让我们在 数据库里创建一个表来存储采集的网页 CREATE TABLE pages; 结果显示错误 ERROR 1113 42000 A table must have at least 1 column 和数据库不同,MySQL数据表必须至少有一列,否则不能创建。为了在MySQL里定义字 段(数据列),你必须在CREATE TABLE 语句后面,把字段的定义放进一个带括 号的、内部由逗号分隔的列表中 CREATE TABLE pages id BIGINT7 NOT NULL AUTO_INCREMENT, title VARCHAR200, content VARCHAR10000, created TIMESTAMP DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY id; 每个字段定义由三部分组成 名称(id、title、created等) 数据类型(BIGINT7、VARCHAR、TIMESTAMP) 其他可选属性(NOT NULL AUTO_INCREMENT) 在字段定义列表的最后,还要定义一个“主键”(key)。MySQL用这个主键来组织表的内 容,便于后面快速查询。在本章后面的内容里,我将介绍如何调整这些主键以提高数据库 的查询速度,但是现在,用表的id列作为主键就可以。 语句执行之后,你可以用DESCRIBE查看数据表的结构 DESCRIBE pages; ----------------------------------------------------------------------- | Field | Type | Null | Key | Default | Extra | ----------------------------------------------------------------------- | id | bigint7 | NO | PRI | NULL | auto_increment | | title | varchar200 | YES | | NULL | | 70 | 第 5 章 | content | varchar10000 | YES | | NULL | | | created | timestamp | NO | | CURRENT_TIMESTAMP | | ----------------------------------------------------------------------- 4 rows in set 0.00 sec 当然,这还是一个空表。你可以在pages表里插入一些测试数据,如下所示 INSERT INTO pages title, content VALUES “Test page title“, “This is some te st page content. It can be up to 10,000 characters long.“; 需要注意的是,虽然pages表里有四个字段(id、title、content、created),但实际上 你只需要插入两个字段(title和content)的数据即可。因为id字段是自动递增的(每 次新插入数据行时MySQL自动增加1),通常不用处理。另外,created字段的类型是 timestamp,默认就是数据加入时的时间戳。 当然,我们也可以自定义四个字段的内容 INSERT INTO pages id, title, content, created VALUES 3, “Test page title“, “ This is some test page content. It can be up to 10,000 characters long.“, “2014- 09-21 102532“; 只要你定义的整数在数据表的id字段里没有,它就可以顺利插入数据表。但是,这么做 非常不好;除非万不得已(比如程序中断漏了一行数据),否则让MySQL自己处理id和 timestamp字段。 现在表里有一些数据了,你可以用很多方法来选择这些数据。下面是几个SELECT语句的 示例 SELECT * FROM pages WHERE id 2; 这条语句告诉MySQL,“从pages表中把id字段中等于2的整行数据全挑选出来”。这个 星号(*)是通配符,表示所有字段,这行语句会把满足条件(WHERE id 2)的所有字段 都显示出来。如果id字段里没有任何一行等于2,就会返回一个空集。例如,下面这个不 区分大小写的查询,会返回title字段里包含“test”的所有行(符合表示MySQL字符 串通配符)的所有字段 SELECT * FROM pages WHERE title LIKE “test“; 但是,如果你的表有很多字段,而你只想返回部分字段怎么办你可以不用星号,而用下 面的方式 SELECT id, title FROM pages WHERE content LIKE “page content“; 这样就只会返回title字段包含“page content”的所有行的id和title两个字段了。 DELETE语句语法与SELECT语句类似 存储数据 | 71 DELETE FROM pages WHERE id 1; 由于数据库的数据删除后不能恢复,所以在执行DELETE语句之前,建议用SELECT确认 一下要删除的数据(本例中,就是用SELECT * FROM pages WHERE id 1查看),然后把 SELECT *换成DELETE就可以了,这会是一个好习惯。很多程序员都有过一些DELETE误操 作的伤心往事,还有一些恐怖故事就是有人慌乱中忘了在语句中放WHERE,结果把所有客 户数据都删除了。别让这种事发生在你身上 还有一个需要介绍的语句是UPDATE UPDATE pages SET title“A new title“, content“Some new content“ WHERE id2; 结合本书的主题,后面我们就只用这些基本的MySQL语句,做一些简单的数据查询、创 建和更新工作。如果你对这个强大数据库的命令和技术感兴趣,推荐你去看Paul DuBois 的MySQL Cookbook( 5.3.3 与Python整合 Python没有内置的MySQL支持工具。不过,有很多开源的库可以用来与MySQL做交互, Python 2.x和Python 3.x版本都支持。最有名的一个库就是PyMySQL( PyMySQL/PyMySQL)。 写到这里的时候,PyMySQL的版本是0.6.2,你可以用下面的命令下载并安装它 curl -L | tar xz cd PyMySQL-PyMySQL-f953785/ python setup.py install 如果需要更新,请检查最新版的PyMySQL,并修改第一行下载链接中的版本号进行更新。 安装完成之后,你就可以使用PyMySQL包了。如果你的MySQL服务器处于运行状态, 应该就可以成功地执行下面的命令(记得把root账户密码加进去) import pymysql conn pymysql.connecthost127.0.0.1, unix_socket/tmp/mysql.sock, userroot, passwdNone, dbmysql cur conn.cursor cur.execute“USE scraping“ cur.execute“SELECT * FROM pages WHERE id1“ printcur.fetchone cur.close conn.close 这段程序有两个对象连接对象(conn)和光标对象(cur)。 72 | 第 5 章 连接/光标模式是数据库编程中常用的模式,不过刚刚接触数据库的时候,有些用户很难 区分两种模式的不同。连接模式除了要连接数据库之外,还要发送数据库信息,处理回滚 操作(当一个查询或一组查询被中断时,数据库需要回到初始状态,一般用事务控制手段 实现状态回滚),创建新的光标对象,等等。 而一个连接可以有很多个光标。一个光标跟踪一种状态(state)信息,比如跟踪数据库的 使用状态。如果你有多个数据库,且需要向所有数据库写内容,就需要多个光标来处理。 光标还会包含最后一次查询执行的结果。通过调用光标函数,比如cur.fetchone,可以 获取查询结果。 用完光标和连接之后,千万记得把它们关闭。如果不关闭就会导致连接泄漏(connection leak),造成一种未关闭连接现象,即连接已经不再使用,但是数据库却不能关闭,因为数 据库不能确定你还要不要继续使用它。这种现象会一直耗费数据库的资源,所以用完数据 库之后记得关闭连接 刚开始的时候,你最想做的事情可能就是把采集的结果保存到数据库里。让我们用前面维 基百科爬虫的例子来演示一下如何实现数据存储。 在进行网络数据采集时,处理Unicode字符串是很痛苦的事情。默认情况下,MySQL也 不支持Unicode字符处理。不过你可以设置这个功能(这么做会增加数据库的占用空间)。 因为在维基百科上我们难免会遇到各种各样的字符,所以最好一开始就让你的数据库支持 Unicode ALTER DATABASE scraping CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; ALTER TABLE pages CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; ALTER TABLE pages CHANGE title title VARCHAR200 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; ALTER TABLE pages CHANGE content content VARCHAR10000 CHARACTER SET utf8mb4 CO LLATE utf8mb4_unicode_ci; 这四行语句改变的内容有数据库、数据表,以及两个字段的默认编码都从utf8mb4 (严格说来也属于Unicode,但是对大多数Unicode字符的支持都非常不好)转变成了 utf8mb4_unicode_ci。 你可以在title或content字段中插入一些德语变音符(umlauts)或汉语字符,如果没有 错误就表示转换成功了。 现在数据库已经准备好接收维基百科的各种信息了,你可以用下面的程序来存储数据 from urllib.request import urlopen from bs4 import BeautifulSoup import re import datetime import random 存储数据 | 73 import pymysql conn pymysql.connecthost127.0.0.1, unix_socket/tmp/mysql.sock, userroot, passwdNone, dbmysql, charsetutf8 cur conn.cursor cur.execute“USE scraping“ random.seeddatetime.datetime.now def storetitle, content cur.execute“INSERT INTO pages title, content VALUES \“s\“, \“s\““, title, content mit def getLinksarticleUrl html urlopen“http//en.wikipedia.org“articleUrl bsObj BeautifulSouphtml title bsObj.find“h1“.get_text content bsObj.find“div“, {“id““mw-content-text“}.find“p“.get_text storetitle, content return bsObj.find“div“, {“id““bodyContent“}.findAll“a“, href pile“/wiki/.*“ links getLinks“/wiki/Kevin_Bacon“ try while lenlinks 0 newArticle links[random.randint0, lenlinks-1].attrs[“href“] printnewArticle links getLinksnewArticle finally cur.close conn.close 这里有几点需要注意首先,charsetutf8要增加到连接字符串里。这是让连接conn把 所有发送到数据库的信息都当成UTF-8编码格式(当然,前提是数据库默认编码已经设置 成UTF-8)。 然后要注意的是store函数。它有两个参数title和content,并把这两个参数加到了一 个INSERT语句中并用光标执行,然后用光标进行连接确认。这是一个让光标与连接操作分 离的好例子;当光标里存储了一些数据库与数据库上下文(context)的信息时,需要通过 连接的确认操作先将信息传进数据库,再将信息插入数据库。 最后要注意的是,finally语句是在程序主循环的外面,代码的最底下。这样做可以保证, 无论程序执行过程中如何发生中断或抛出异常(当然,因为网络很复杂,你得随时准备遭 遇异常),光标和连接都会在程序结束前立即关闭。无论你是在采集网络,还是处理一个 打开连接的数据库,用try.finally都是一个好主意。 虽然PyMySQL规模并不大,但是里面有一些非常实用的函数本书并没有介绍。具体请参 考Python的DBAPI标准文档(http//legacy.python.org/dev/peps/pep-0249/)。 74 | 第 5 章 5.3.4 数据库技术与最佳实践 有些人的整个职业生涯都在学习、优化和创造数据库。我不是这类人,这本书也不是那类 书。但是,和计算机科学的很多主题一样,有一些技巧你其实可以很快地学会,它们可以 让你的数据库变得更高效,让应用的运行速度更快。 首先,给每个数据表都增加一个id字段,不会出什么问题。MySQL里所有的表都至少有 一个主键(就是MySQL用来排序的字段),因此MySQL知道怎么组织主键,通常数据库 很难智能地选择主键。究竟是用人造的id字段作为主键,还是用那些具有唯一性属性的 字段作为主键,比如username字段,数据科学家和软件工程师已经争论了很多年,但我更 倾向于主动创建一个id字段。这样做的原因一两句话难以说清,不过对于一些非企业级 系统的数据库,你还是应该用自增的id字段作为主键。 其次,用智能索引。字典(指的是常用的工具书,不是指Python的字典对象)是按照字母 顺序排列的单词表。这样做让你在任何时候都能快速地找到一个单词,只要你知道这个单 词是如何拼写的就行。你还可以把字典想象成另一种形式,将单词按照单词含义的字母顺 序进行排列。如果你没玩过一些奇怪的游戏,比如危险边缘(Jeopardy)智力游戏,就不 能理解游戏的含义,这样的字典就没法用了。但是在数据库查询的工作里,这种按照字段 含义进行排序的情况时有发生。比如,你的数据库里可能有一个字段经常要查询 SELECT * FROM dictionary WHERE definition“A small furry animal that says meow“; -------------------------------------------------- | id | word | definition | -------------------------------------------------- | 200 | cat | A small furry animal that says meow | -------------------------------------------------- 1 row in set 0.00 sec 你可能非常想给这个表增加一个额外的键(除了已经存在的主键id之外),让查询变得更 快。但是,增加额外的索引需要占用更多的空间,而且插入新行的时候也需要花费更多的 时间。为了让事情简单点儿,你可以让MySQL只检索查询列的一部分字符。比如下面的 命令创建了一个查询definition字段前16个字符的智能索引 CREATE INDEX definition ON dictionary id, definition16; 这个索引比全文查询的速度要快很多,而且不需要占用过多的空间和处理时间。 最后一点是关于数据查询时间和数据库空间的问题。一个常见的误区就是在数据库中存储 大量重复数据,尤其是在做大量自然语言数据的网络数据采集任务时。举个例子,假如你 想统计网站突然出现的一些词组的频率。这些词组也许可以从一个现成的列表里获得,也 许可以通过文本分析算法自动提取。最终你可能会把词组储存成下表的形式 ---------------------------------------------------------- | Field | Type | Null | Key | Default | Extra | 存储数据 | 75 ---------------------------------------------------------- | id | int11 | NO | PRI | NULL | auto_increment | | url | varchar200 | YES | | NULL | | | phrase | varchar200 | YES | | NULL | | ---------------------------------------------------------- 每当你发现一个词组就在数据库中增加一行,同时把URL记录下来。但是,如果把这些 数据分成三个表,你就可以看到数据库占用的空间会大大降低 DESCRIBE phrases ---------------------------------------------------------- | Field | Type | Null | Key | Default | Extra | ---------------------------------------------------------- | id | int11 | NO | PRI | NULL | auto_increment | | phrase | varchar200 | YES | | NULL | | ---------------------------------------------------------- DESCRIBE urls --------------------------------------------------------- | Field | Type | Null | Key | Default | Extra | --------------------------------------------------------- | id | int11 | NO | PRI | NULL | auto_increment | | url | varchar200 | YES | | NULL | | --------------------------------------------------------- DESCRIBE foundInstances ---------------------------------------------------------- | Field | Type | Null | Key | Default | Extra | ---------------------------------------------------------- | id | int11 | NO | PRI | NULL | auto_increment | | urlId | int11 | YES | | NULL | | | phraseId | int11 | YES | | NULL | | | occurrences | int11 | YES | | NULL | | ---------------------------------------------------------- 虽然表定义的结构变复杂了,但是新增的字段就是id字段。它们是整数,不会占用很多 空间。另外,每个URL和词组都只会储存一次。 除非你安装了第三方包或保存详细的数据库日志,否则你无法掌握数据库里数据增加、更 新或删除的具体时间。因此,如果需要对数据可用的空间、变更的频率和变更的重要性进 行分析,你应该考虑在数据新增、更新或删除时加一个时间戳。 5.3.5 MySQL里的“六度空间游戏” 在第3章,我们介绍过“维基百科六度分隔”问题,其目标是通过一些词条链接寻找两个 词条间的联系(即找出一条链接路径,只要点击链接就可以从一个维基词条到另一个维基 词条)。 为了解决这个问题,我们不仅需要建立网络爬虫采集网页(之前我们已经做过),还要把 76 | 第 5 章 采集的信息以某种形式存储起来,以便后续进行数据分析。 前面介绍过的自增的id字段、时间戳以及多份数据表在这里都要用到。为了确定最合理 的信息存储方式,你需要先想想游戏规则。一个链接可以轻易地把页面A连接到页面B。 同样也可以轻易地把页面B连接到页面A,不过这可能是另一条链接。我们可以这样识 别一个链接,即“页面A存在一个链接,可以连接到页面B”。也就是INSERT INTO links fromPageId, toPageId VALUES A, B;(其中,“A”和“B”分别表示页面的ID号)。 因此需要设计一个带有两张数据表的数据库来分别存储页面和链接,两张表都带有创建时 间和独立的ID号,代码如下所示 CREATE TABLE wikipedia.pages id INT NOT NULL AUTO_INCREMENT, url VARCHAR255 NOT NULL, created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY id; CREATE TABLE wikipedia.links id INT NOT NULL AUTO_INCREMENT, fromPageId INT NULL, toPageId INT NULL, created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY id; 注意,这里和前面打印页面标题的爬虫不同,我没有在页面数据表里使用页面标题字段, 为什么这么做呢其实是因为页面标题要在你进入页面后读取内容才能抓到。那么,如果 我们想创建一个高效的爬虫来填充这些数据表,那么只存储页面的链接就可以保存词条页 面了,甚至不需要访问词条页面。 当然并不是所有网站都具有这个特点,但是维基百科的词条链接和对应的页面标题是可以 通过简单的操作进行转换的。例如,http//en.wikipedia.org/wiki/Monty_Python的后面就是 页面标题“Monty Python”。 下面的代码会把“贝肯数”(一个页面与凯文 贝肯词条页面的链接数)不超过6的维基 百科页面存储起来 from bs4 import BeautifulSoup import re import pymysql conn pymysql.connecthost127.0.0.1, unix_socket/tmp/mysql.sock,user root, passwdNone, dbmysql, charsetutf8 cur conn.cursor cur.execute“USE wikipedia“ def insertPageIfNotExistsurl cur.execute“SELECT * FROM pages WHERE url s“, url 存储数据 | 77 if cur.rowcount 0 cur.execute“INSERT INTO pages url VALUES s“, url mit return cur.lastrowid else return cur.fetchone[0] def insertLinkfromPageId, toPageId cur.execute“SELECT * FROM links WHERE fromPageId s AND toPageId s“, intfromPageId, inttoPageId if cur.rowcount 0 cur.execute“INSERT INTO links fromPageId, toPageId VALUES s, s“, intfromPageId, inttoPageId mit pages set def getLinkspageUrl, recursionLevel global pages if recursionLevel 4 return; pageId insertPageIfNotExistspageUrl html urlopen“http//en.wikipedia.org“pageUrl bsObj BeautifulSouphtml for link in bsObj.findAll“a“, href pile“/wiki/.*“ insertLinkpageId, insertPageIfNotExistslink.attrs[href] if link.attrs[href] not in pages 遇到一个新页面,加入集合并搜索里面的词条链接 newPage link.attrs[href] pages.addnewPage getLinksnewPage, recursionLevel1 getLinks“/wiki/Kevin_Bacon“, 0 cur.close conn.close 用递归实现那些需要运行很长时间的代码,通常是一件复杂的事情。在本例中,变量 recursionLevel被传递到getLinks函数里,用来跟踪函数递归的次数(每完成一次递归, recursionLevel就加1)。当recursionLevel值到5的时候,函数会自动返回,不会继续递 归。这个限制可以防止数据太大导致内存堆栈溢出。 需要注意的是,这个程序可能要运行好几天才会结束。虽然我自己运行过它,但是我的数 据库里只保持了一点点贝肯数不超过6的词条,因为维基百科服务器会拒绝程序的请求。 但是,这些数据对后面分析维基百科词条的链接路径问题已经足够了。 关于这个问题的补充和最终答案,将在第8章关于有向图的问题里介绍。 5.4 Email 与网页通过HTTP协议传输一样,邮件是通过SMTP(Simple Mail Transfer Protocol,简 78 | 第 5 章 单邮件传输协议)传输的。而且,和你用网络服务器的客户端(浏览器)处理那些通过 HTTP协议传输的网页一样,Email服务器也有客户端,像Sendmail、Postfix和Mailman 等,都可以收发邮件。 虽然用Python发邮件很容易,但是需要你连接那些正在运行SMTP协议的服务器。在服 务器或本地机器上设置SMTP客户端有点儿复杂,也超出了本书的介绍范围,但是有很多 资料可以帮你解决问题,如果你用的是Linux或Mac OS X系统,参考资料会更丰富。 下面的代码运行的前提是你的电脑已经可以正常地运行一个SMTP客户端。(如果要调整 代码用于远程SMTP客户端,请把localhost改成远程服务器地址。) 用Python发一封邮件只要9行代码 import smtplib from email.mime.text import MIMEText msg MIMEText“The body of the email is here“ msg[Subject] “An Email Alert“ msg[From] “ryan “ msg[To] “webmaster “ s smtplib.SMTPlocalhost s.send_messagemsg s.quit Python有两个包可以发送邮件smtplib和email。 Python的email模块里包含了许多实用的邮件格式设置函数,可以用来创建邮件“包 裹”。下面的示例中使用的MIMEText对象,为底层的MIME(Multipurpose Internet Mail Extensions,多用途互联网邮件扩展类型)协议传输创建了一封空邮件,最后通过高层的 SMTP协议发送出去。MIMEText对象msg包括收发邮箱地址、邮件正文和主题,Python通 过它就可以创建一封格式正确的邮件。 smtplib模块用来设置服务器连接的相关信息。就像MySQL服务器的连接一样,这个连接 必须在用完之后及时关闭,以避免同时创建太多连接而浪费资源。 把这个简单的邮件程序封装成函数后,可以更方便地扩展和使用 import smtplib from email.mime.text import MIMEText from bs4 import BeautifulSoup from urllib.request import urlopen import time def sendMailsubject, body msg MIMETextbody 存储数据 | 79 msg[Subject] subject msg[From] “christmas_alerts “ msg[To] “ryan “ s smtplib.SMTPlocalhost s.send_messagemsg s.quit bsObj BeautifulSoupurlope

    注意事项

    本文(Python网络数据采集.pdf)为本站会员(小魏子好文库)主动上传,吾爱文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知吾爱文库(发送邮件至123456@qq.com或直接QQ联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    copyright@ 2008-2013 吾爱文库网站版权所有
    经营许可证编号:京ICP备12026657号-3

    收起
    展开