文章目录

  • HTML正文抽取
  • 多媒体文件抽取
  • Email提醒

HTML正文抽取

HTML正文存储主要分为两种格式:JSON和CSV

储存为JSON

需求:抽取小说标题、章节、章节名称和链接

首先使用Requests访问http://seputu.com/,获取HTML文档内容,并打印文档内容

import requestsuser_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)"
headers = {"User-Agent" : user_agent}r = requests.get("http://seputu.com/", headers = headers)
#指定使用utf-8解析文档
r.encoding = "utf-8"
#打印文档内容
print(r.text)

分析该网页HTML结构,确定要抽取标记的位置,其中标题和章节都被包含在<dir class = “muln” 标记下,标题位于其中的《dir class = “muln-title”》下的《h2》中,章节位于其中的《dir class = “box”》下的《a》中

import requests
from bs4 import BeautifulSoup
user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)"
headers = {"User-Agent" : user_agent}r = requests.get("http://seputu.com/", headers = headers)
#指定使用utf-8解析文档
r.encoding = "utf-8"
#打印文档内容
# print(r.text)soup = BeautifulSoup(r.text, "html.parser", from_encoding="utf-8")#其中"html.parser"是python标准库默认解析器
for mulu in soup.find_all(class_="mulu"):h2 = mulu.find("h2")if h2 != None:h2_title = h2.string #获取标题# print(h2_title)for a in mulu.find_all("a"):if a.get("title") != None:href = a.get("href") # 获取每个章节的连接# print(href)box_title = a.get("title") # 获取章节名称print(href, box_title)
  • 已成功获取标题、章节,接下来将数据存储为JSON
import requests
from bs4 import BeautifulSoup
import json
user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)"
headers = {"User-Agent" : user_agent}r = requests.get("http://seputu.com/", headers = headers)
#指定使用utf-8解析文档
r.encoding = "utf-8"
#打印文档内容
# print(r.text)soup = BeautifulSoup(r.text, "html.parser", from_encoding="utf-8")#其中"html.parser"是python标准库默认解析器content = []# 找出所有含有mulu的文档
for mulu in soup.find_all(class_="mulu"):# print(mulu) #查看# 获取h2标签Tagh2 = mulu.find("h2")# print(h2) #查看if h2 != None:h2_title = h2.string #获取h2中的文本标题# print(h2_title) #查看list = []# 在每个mulu中获取章节名称及其链接标签afor a in mulu.find(class_="box").find_all("a"):href = a.get("href") # 从a标签中获取每个章节的连接# print(href) #查看box_title = a.get("title") # 从a标签中获取章节名称# print(box_title) # 查看list.append({"href" : href, "box_title" : box_title})content.append({"title" : h2_title, "content" : list})with open("UserPython.json", "w", encoding="utf-8") as fp:json.dump(content, fp=fp, indent=4, ensure_ascii= False)

存储为CSV
CSV(称为逗号分隔值,有时也称为字符分隔值,因为分隔符也可以不是逗号),其文本以纯文本形式存储表格数据(数字和文本)。纯文本意味着该文件是一个字符序列,不含必须像二进制数字那样被解读的数据
CSV文件由任意数目的记录组成,记录间以某种换行符分隔;每条记录由字段组成,字段间的分隔符是其他字符或字符串,最常见的是逗号或制表符。通常,所有记录都有完全相同的字段序列。CSV文件示例如下

python使用CSV库来读写CSV文件。要将上面CSV文件的示例内容写成csvTest.csv文件,需要用到Writer对象,代码如下

import csvheaders = ["ID", "UserName", "Password", "Age", "Country"]rows = [(1001,"userH","userH123", 19, "China"),(1002, "userN", "userN123", 20, "USA"),(1003, "userB", "userB123", 20, "UK")]with open("csvTest.csv", "w") as f:f_csv = csv.writer(f)f_csv.writerow(headers)f_csv.writerows(rows)

里面的rows列表中的数据元组也可以是字典数据

import csvheaders = ["ID", "UserName", "Password", "Age", "Country"]rows = [{"ID" : 1001, "UserName" : "userH", "Password" : "userH123", "Age" : 19, "Country" : "China"},{"ID" : 1002, "UserName" : "userN", "Password" : "userN123", "Age" : 20, "Country" : "USA"},{"ID" : 1003, "UserName" : "userB", "Password" : "userB123", "Age" : 20, "Country" : "UK"}]with open("csvTest.csv", "w") as f:f_csv = csv.DictWriter(f, headers)f_csv.writeheader()f_csv.writerows(rows)

上面的代码中,row会是一个表列,因此,为了访问某个字段,你需要使用索引,如row[0]访问ID,row[3]访问Age。由于这种索引访问通常会引起混淆,因此可以考虑使用命名元组。示例如下

import csvfrom collections import namedtuplewith open("csvTest.csv") as f:f_csv = csv.reader(f)headings = next(f_csv)Row = namedtuple("Row", headings)for r in f_csv:row = Row(*r)print(row.UserName, row.Password)# print(row)
#########################################
userH userH123
userN userN123
userB userB123

它允许使用列名如row.UserName和row.Password代替下标访问。需要注意的是这个只有列名合法的Python标识符的时候才生效

除了使用命名组之外,另外一个解决办法就是读取到一个字典序列中,示例如下

import csvwith open("csvTest.csv") as f:f_csv = csv.DictReader(f)for row in f_csv:print(row["UserName"], row["Password"])# print(row.get("UserName"), row.get("Password"))###########################
userH userH123
userN userN123
userB userB123

这样就可以使用列名去访问每一行的数据了。如row[“UserName”]或者row.get(“UserName”)

多媒体文件抽取

存储媒体文件主要有两种方式:只获取文件的URL链接,或者直接将媒体文件下载到本地。这里主要介绍urllib模块提供的urlretrieve()方法。urlretrieve()方法直接将远程数据下载到本地,方法原型如下

urlretrieve(url, filename=None, reporthook=None, data=None)

参数说明:
filename:参数filename指定了存储的本地路径(如果参数未指定,urllib会生成一个临时文件保存数据)
reporthook:参数reporthook是一个回调函数。当连接上服务器以及相应的数据块传输完毕时会触发该回调函数,我们可以利用这个回调函数来显示当前的下载进度
data:参数data指post到服务器的数据,该方法返回一个包含两个元素的(filename,headers)元组,filename表示保存到本地的路径,headers表示服务器的响应头

实践:提取天堂图片网的图片(http://www.ivsky.com/tupian/ziranfengguang/)
需求:提取当前网址中的图片链接,并将图片下载到指定目录

import urllib.request
from lxml import etree
import requestsdef Schedule(blocknum, blocksize, totalsize):""":blocknum: 已经下载的数据块:blocksize: 数据块的大小:totalsize: 远程文件的大小"""per = 100.0*blocknum*blocksize/totalsizeif per > 100:per = 100print("当前下载进度:%d" % per)user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)"
headers = {"User-Agent" : user_agent}r = requests.get("http://www.ivsky.com/tupian/ziranfengguang/", headers = headers)#使用lxml解析网页
html = etree.HTML(r.text)
img_urls = html.xpath(".//img/@src") #先找到所有的img
i = 0
for img_urls in img_urls:urllib.request.urlretrieve(img_urls,r'E:\Photo\img%s.jpg'%i, Schedule)i += 1

❤️ 先将当前网址的img标记中的src属性提取出来,交给urllib.request.urlretrieve函数去下载,自动回调Schedule函数,显示当前下载的进度

Email提醒

当爬虫在运行过程中遇到异常或者服务器遇到问题,可以通过Email及时向自己报告

发送邮件的协议是STMP,Python内置对SMTP的支持,可以发送纯文本邮件、HTML邮件以及带附件的邮箱。Python对SMTP支持有smtplib和email两个模块,email负责构造邮件,smtplib负责发送邮件

将邮箱的SMTP开启后,我们来构造一个纯文本邮件:

from email.mime.text import MIMEText
msg = MIMETest(“Python爬虫运行异常,异常信息为遇到HTTP 403”, “plain”, “utf-8”)

构造MIMEText对象时需要3个参数:
邮件正文:如"Python爬虫运行异常,异常信息为遇到HTTP 403"
MIME的subtype,传入“plain”表示纯文本,最终的MIME就是“text/plain”
设置编码格式,UTF-8编码保证多语言兼容性

接着设置邮件的发件人、收件人和邮件主题等信息,并通过SMTP发送出去,代码如下

from email.mime.text import MIMEText
from email.header import Header
from email.utils import parseaddr, formataddr
import smtplibdef _format_addr(s):name, addr =  parseaddr(s)return formataddr((Header(name, "utf-8").encode(),addr))#发件人地址
from_addr = "xxxxxxxxxxxxx@163.com"
#邮箱密码
password="passwd"
#收件人地址
to_addr = "xxxxxxxxxxx@qq.com"
#163网易邮箱服务器地址
smtp_server = "smtp.163.com"
#设置邮箱信息
msg = MIMEText("Python爬虫运行异常,异常信息为遇到HTTP 403", "plain", "utf-8")
msg["From"] = _format_addr("一号爬虫<%s>" % from_addr)
msg["To"] = _format_addr("管理员<%s>" % to_addr)
msg["Subject"] = Header("一号爬虫运行状态", "utf-8").encode()
#发送邮件
server = smtplib.SMTP(smtp_server, 25)
server.login(from_addr, password)
server.sendmail(from_addr, [to_addr], msg.as_string())
server.quit()

有时候我们发送的可能不是纯文本,需要发送HTML邮件,将异常网页信息发送出去。在构造MIMEText对象时,把HTML字符串传进去,再把第二个参数由“plain”改为“html”就可以了,示例如下

msg = MIMEText('<html><body><h1>Hello python</h1>' + '<p>异常网页<a href = "http://www.hhhh.com">...</p>' + '</body></html>', "html", "utf-8")

Python爬虫_数据存储相关推荐

  1. python爬虫数据提取_入门Python爬虫——提取数据篇

    原标题:入门Python爬虫--提取数据篇 作者: 李菲 来源:人工智能学习圈 前言 在提取数据这一环节,爬虫程序会将我们所需要的数据提取出来.在上一篇文章<入门Python爬虫 -- 解析数据 ...

  2. Python爬虫-数据处理与存储

    Python爬虫-数据处理与存储 数据处理 ​ 可以使用pandas模块来实现数据处理,pandas是一个开源的并且通过BSD许可的库.它主要为Python语言提供高性能.易于使用数据结构和数据分析工 ...

  3. Android基础_数据存储

    2019独角兽企业重金招聘Python工程师标准>>> Android基础_数据存储 Android数据存储的几种形式 继承SQLiteOpenHelper public class ...

  4. Python爬虫以及数据可视化分析

    Python爬虫以及数据可视化分析之Bilibili动漫排行榜信息爬取分析 简书地址:https://www.jianshu.com/u/40ac87350697 简单几步,通过Python对B站番剧 ...

  5. Python爬虫_案例分析(二)

    Python爬虫_案例分析(二) 一.电影天堂案例 import scrapy from scrapy_movie.items import ScrapyMovieItem class MvSpide ...

  6. python 爬虫与数据可视化

    python 爬虫与数据可视化 1.引言 Web已经成为日新月异迅速发展的网络信息技术中的信息载体,如何有效地提取和利用搜索引擎获得互联网最有用的.可以免费公开访问的数据集,查找用户所需的价值数据或者 ...

  7. Python 爬虫找到数据了 re XPath requests Pool

    Python 爬虫找到数据了 re & XPath & requests & Pool 2018.06.16 23:18 88浏览 字号 是的,爬虫就是为了获取数据.在获取的数 ...

  8. Python爬虫_某宝网案例

    Python爬虫_某宝网案例 一.导入第三方库,确定url,定义headers ,伪装爬虫代码 import requests url = 'https://s.taobao.com/search?q ...

  9. python爬虫_抓取瓦片图片信息并将其拼接_以mapbar为例(适用交通工程类专业)

    python爬虫_抓取瓦片图片信息并将其拼接_以mapbar为例(适用交通工程类专业) 这次就以mapbar为例爬取道路交通拥堵情况 第一步,瓦片标号解析 第二步,拼url,然后下载 第三步,图片拼接 ...

最新文章

  1. 电脑任务管理器_安国戴尔电脑显示器维修,服务至上
  2. mysql批量insert bug_MySQL Bug insert into on duplicate key update 语法更新 text blob 大字段导致 MySQL crash...
  3. 2019以太坊开发者及应用峰会(北京)
  4. C# Winform 通过FlowLayoutPanel及自定义的编辑控件,实现快速构建C/S版的编辑表单页面...
  5. 解决Cesium无法加载出地球的问题
  6. linux——vim命令详细说明
  7. 中国银屑病患者中银屑病关节炎的患病率和特征
  8. Selenium操作页面元素
  9. python很有用吗_Python之父:为什么操作符很有用?
  10. delphi编写ocx控件步骤
  11. 隐藏播放器html代码大全,播放器代码大全
  12. apksigner --> apk签名工具
  13. OpenCV图像处理——阈值处理/二值化(python实现和c++实现)
  14. 张朝阳陈天桥牵手周鸿祎 马化腾仗势欺人孤独求败
  15. php octet stream,为什么上传图片时,type 显示application/octet-stream 呢? 原
  16. ./configure, make, sudo make install 的含义
  17. stl文件用proe怎么打开_3dmax怎么导入stl文件?如何将proe的文件导入3dmax进行渲染?...
  18. 关于SVG图片鼠标变为小手
  19. vue-router 路由 pushstate replacestate popstate 详解
  20. Alpine的安装、介绍与相关配置

热门文章

  1. 保存时间 默认_操作技能|WORD文档没保存,有办法恢复吗?
  2. python读取doc文件_Linux 下Python 读取Word文档内容的方法
  3. html选择按钮select,Html选择使用select来改变一个按钮的链接使用Javascript
  4. 安装python缺少dll_python报错DLL load failed:找不到模块怎么解决?
  5. Java日志框架-logback的介绍及配置使用方法(纯Java工程)
  6. Log图文详解(Log.v,Log.d,Log.i,Log.w,Log.e)!
  7. MySQL使用触发器实现check约束功能
  8. IOS之block,一点小心得
  9. mysqldump备份表中有大字段失败的排错过程
  10. maven Web项目添加数据源支持,包括Oracle、Mysql