目录:
- 前言:
- 一,媒体文件
- 二,把数据存储到CSV
- 三,邮件email发送
- 四,拓展:
前言:
虽然在命令行里打印出运行效果比较直观,但是随着数据不断增多(程序可能存储不起来),并且需要进行数据分析 (要有采集的相关数据),和远程使用大部分网络爬虫时,我们需要把采集到的数据存储起来。 本文将介绍三种主要的数据管理方法,对绝大多数应用都适用:
1.如果你准备创建一个网站 的后端服务或者创建自己的 API,那么可能都需要让爬虫把数据写入数据库;
2. 如果你需要 一个快速简单的方法收集网上的文档,然后存到你的硬盘里,那么可能需要创建一个文件 流(file stream)来实现;
3. 如果还要为偶然事件提个醒儿,或者每天定时收集当天累计的数 据,就给自己发一封邮件吧!
抛开与网络数据采集的关系,大数据存储和与数据交互的能力,在新式的程序开发中也已经是重中之重了。而以后的项目开发,数据存储是个重要的组成部分,我们要把它弄懂。
一,媒体文件
存储媒体文件有两种主要的方式:
(1)只获取文件 URL 链接;
(2)直接把源文件下载下来。
你可以通过媒体文件所在的 URL 链接直接引用它。这样做的优点如下:
• 爬虫运行得更快,耗费的流量更少,因为只要链接,不需要下载文件。
• 可以节省很多存储空间,因为只需要存储 URL 链接就可以。
• 存储 URL 的代码更容易写,也不需要实现文件下载代码。
• 不下载文件能够降低目标主机服务器的负载。
不过这么做也有一些缺点:
• 这些内嵌在你的网站或应用中的外站 URL 链接被称为盗链(hotlinking),使用盗链可 能会让你麻烦不断,每个网站都会实施防盗链措施。
• 因为你的链接文件在别人的服务器上,所以你的应用就要跟着别人的节奏运行了。
• 盗链是很容易改变的。如果你把盗链图片放在博客上,要是被对方服务器发现,很可能被恶搞。如果你把 URL 链接存起来准备以后再用,可能用的时候链接已经失效了,或者是变成了完全无关的内容。
• 现实中的网络浏览器不仅可以请求 HTML 页面并切换页面,它们也会下载访问页面上 所有的资源。下载文件会让你的爬虫看起来更像是人在浏览网站,这样做反而有好处。
究竟是存储文件,还是只存储文件的 URL 链接,可以想想这些文件是要 多次使用,还是放进数据库之后就只是等着“落灰”,如果答案是后者, 那么最好还是只存储这些文件的 URL 吧。如果答案是前者,那么就继续往下看!
在 Python 3.x 版本中,urllib.request.urlretrieve 可以根据文件的 URL 下载文件:
from urllib.request import urlopen
from urllib.request import urlretrieve
from bs4 import BeautifulSoup
html=urlopen("http://www.pythonscraping.com")
soup=BeautifulSoup(html,"html.parser")
image_url=soup.find("a", {"id": "logo"}).find("img")["src"]#搜索到对应图片url,供urlretrieve函数使用;
urlretrieve(image_url,"logo.jpg")#可以自定义保存文件名称;
输出效果如下:
如果你只需要下载一个文件,而且知道如何获取它,以及它的文件类型,上面的程序就可以满足了。下面的程序会把 对应网页上所有 src 属性的(图片)文件都下载下来:
from urllib.request import urlretrieve
from urllib.request import urlopen
from bs4 import BeautifulSoup
import os
def clearUrl(base_url,link):#对图片的url进行清理,使得符合程序访问要求的格式;
if link.startswith("http://www."):#统一处理成以http://开头的链接格式
url="http://"+link[11:]
elif link.startswith("http://"):
url=link
elif link.startswith("www."):
url=url = "http://"+link[4:]
else:
url= base_url+"/"+link
if base_url not in url: #针对外站和无用链接的处理
return None
return url
def pathFile(base_url,url,inpath):
path=url.replace("www.","")
path=path.replace(base_url,"")#将链接处理,用网页文件目录创建系统文件目录,方便管理;
path=inpath+path
directory = os.path.dirname(path)
if not os.path.exists(directory):#判断是否有文件目录存在,默认同py程序目录;
os.makedirs(directory)#没有则创建,定义好首层保存文件名就行
return path
def main():
lists=[]#定义新空列表,用于后面去重,减少重复的下载链接,提升速度;
base_url="http://m.dili360.com"#爬取该网站的一些简单图片;
inpath="国家地理图片下载"#同程序目录下的存储文件下,如果没有后面可以创建;
html=urlopen(base_url)
soup=BeautifulSoup(html,"html.parser")
url_list=soup.findAll("img",src=True)#找出src属性并对应值存在的标签,比较特殊的用法;
for i in url_list:
if i["src"] not in lists:
lists.append(i["src"])
for link in lists:
url=clearUrl(base_url,link)
if url is not None:
print("存在链接:"+url)#打印链接
path=pathFile(base_url,url,inpath)
urlretrieve(url,path)
main()
输出效果如下(打印+下载图片文件)
总结:
这个程序首先使用 Lambda 函数选择首页上所有带 src 属性的标签。(findAll中允许特定函数作为参数的特殊用法,但是函数返回结果应该为布尔类型,拓展里会有介绍,这个点可以学习记起来,后面检索标签会快很多),然 后对 URL 链接进行清理和标准化,获得文件的绝对路径(而且去掉了外链)。最后,每个文件都会下载到同程序目录的 自定义文件里。但该程序的功能还是比较简单的 ,如果需要丰富功能,可以以这个为基础(思路)来拓展。这里 Python 的 os 模块用来获取每个下载文件的目标文件夹,建立完整的路径。os 模块是 Python 与操作系统进行交互的接口,它可以操作文件路径,创建目录,获取运行进程和环 境变量的信息,以及其他系统相关的操作。
程序运行注意事项 :
这个程序会把页面上所有的文件 下载到你的硬盘里,可能会包含一些 bash 脚本、.exe 文件,甚至可能是恶意 软件(malware)。 所以千万不要以管理员权限来运行未知的文件,这样会提高电脑安全性。 为了防范恶意软件,记得经常备份重要的文 件,不要在硬盘上存储敏感信息,小心驶得万年船。
二,把数据存储到CSV
CSV(Comma-Separated Values,逗号分隔值)是存储表格数据的常用文件格式。Microsoft Excel 和很多应用都支持 CSV 格式,因为它很简洁。下面就是一个 CSV 文件的例子:
和 Python 一样,CSV 里留白(whitespace)也是很重要的:每一行都用一个换行符分隔, 列与列之间用逗号分隔(因此也叫“逗号分隔值”,顾名思义)。CSV 文件还可以用 Tab 字符或其他字 符分隔行,但是不太常见,用得不多。
Python 的 csv 库可以非常简单地修改 CSV 文件,甚至从零开始创建一个 CSV 文件:
import csv
csv_item = open("测试.csv", 'w+')#打开文件,默认同文件目录下,若无则创建文件;
try:
item = csv.writer(csv_item)#创建一个 csv.writer 对象
item.writerow(('number', 'number plus 2', 'number times 2')) #表头
for i in range(10):
item.writerow( (i, i*2, i*3))#写入行信息;
finally:
csv_item.close()#关闭文件状态;
注意:Python 新建文件的机制考虑得非常周到(bullet-proof)。如果 不存在,Python 会自动创建文件(但不会自动创建文件夹)。如果文件已经存在,Python 会 用新的数据覆盖 test.csv 文件。
运行完成后,你会看到一个 CSV 文件(如果系统有相关Excel或CSV类编辑软件,这类CSV文件会被自动识别的),并被MSExcel打开时是像第二张图那样:
网络数据采集的一个常用功能就是获取 HTML 表格并写入 CSV 文件。网页表格中用了许多复杂 的 HTML 表格,用到了颜色、链接、,序,以及其他在写入 CSV 文件之前需要忽略的 HTML 元素。现在,我们开始编写一个可以爬取百度百科词条中一个表格并写入CSV文件中的程序:用 BeautifulSoup 和 get_text() 函数来轻松实现:
from urllib.request import urlopen
from bs4 import BeautifulSoup
import csv
html=urlopen("https://baike.baidu.com/item/%E6%94%B9%E9%9D%A9%E5%BC%80%E6%94%BE")
soup=BeautifulSoup(html,"html.parser")
table=soup.find("table",{"log-set-param":"table_view"})#找到所需表格标签,事前需观察表格标签特点;
rows=table.findAll("tr")#tr标签是表格的每一行的标签
csv_item = open("1980-2010年中国大陆GDP列表.csv", 'w+')#打开文件,默认同文件目录下,若无则创建文件和文件夹;
item = csv.writer(csv_item)#创建一个csv.writer对象--item;
try:
for row in rows:#遍历每一行,遵循先行后列的规则;
csv_list=[]
for i in row.findAll("div"): #遍历行中每一列;
csv_list.append(i.get_text())#向列表添加表格行中每一列,即每单个含文本标签;
item.writerow(csv_list)#将一行中的每个列标签都写入CSV文件中,对应实际中的每一行;
print("爬取表格数据和写入文件成功!!!")
finally:
csv_item.close()#关闭文件状态;
效果如下:
注意事项 :
如果你有很多 HTML 表格,且每个都要转换成 CSV 文件,或者许多 HTML 表格都要 汇总到一个 CSV 文件,那么把这个程序整合到爬虫里以解决问题非常好。但是,如果 你只需要做一次这种事情,那么更好的办法就是:复制粘贴。选择 HTML 表格内容然 后粘贴到 Excel 文件里,可以另存为 CSV 格式,不需要写代码就能搞定!
三,邮件email发送
与网页通过 HTTP 协议传输一样,邮件是通过 SMTP(Simple Mail Transfer Protocol,简单邮件传输协议)传输的。而且,和你用网络服务器的客户端(浏览器)处理那些通过 HTTP 协议传输的网页一样,Email 服务器也有客户端,像 Sendmail、Postfix 和 Mailman 等,都可以收发邮件。
虽然用 Python 发邮件很容易,但是需要你连接那些正在运行 SMTP 协议的服务器。在服务器或本地机器上设置 SMTP 客户端,这里需要一些设置步骤,还有一些用法,后面会写一个专门的自动邮箱发送程序实例的文章(敬请关注,后面底下拓展会有链接的),而编写利用的第三方库是yagmail库,它简单易上手,而且只需编写几行的代码就可以实现。
下面的发送一件邮件代码运行的前提是(已经向邮箱网站申请开通SMTP服务功能了):
import yagmail
#以下涉及到账号信息的,已经过处理,根据自己的信息来填写
user='@163.com'#发送方邮箱地址
password=''#申请过来的密码
port='465'#端口,会提供的
host='smtp.163.com'#对应的邮箱SMTP服务器地址
mail = yagmail.SMTP(user, password, host, port)#设置基本账号参数,创建一个mail类实例
mail.send(to=["@qq.com"],subject=["LOVE"],contents=["I LOVE YOU!"])#使用其中的方法,发送其中所需发送的内容;
输出效果如下:
自动邮件发送可以有很多用途:它 可以发送网站访问失败、应用测试失败的异常情况,也可以在 Amazon 网站上出现了一款 卖到断货的畅销品时通知你——这些都是挂历做不到的事情。
现在我们关注的是python的email邮件发送的实现介绍,不做详细地学习,不过后面拓展会有专门的实例文章可供学习!