Python爬虫实战-抓取《盗墓笔记》所有章节及链接
本次以一个盗墓笔记的小说阅读网(http://seputu.com)为例,抓取盗墓笔记的标题、章节名和链接,如下图
前提:
这是一个静态网站,标题、章节都不是由JavaScript动态加载的,无代理,无登录,无验证。
分析目标url的HTML结构:
分析结果如下:
标题和章节都被包含在<div class="mulu">标记下,标题位于其中的<div class="mulu-title"标记下的<h2>标签中,章节位于其中的<div class="box"下的<a>标签中。
爬取思路:
requests(http请求)
BeautifulSoup(页面解析)
json&CSV&txt(数据存储)
代码构造如下:
一:存储为TXT文本文件:
先导入需要库:
from bs4 import BeautifulSoup
import requests
设置请求头、目标url,使用get方法请求:
url = “http://seputu.com“
user_agent = “Mozilla/5.0 (Windows NT 6.3; WOW64)”
headers = {“User_agent”: user_agent}
req = requests.get(url, headers=headers)
使用BeautifulSoup进行网页解析:
# 指定htm.parser为解析器
soup = BeautifulSoup(req.text, "html.parser")
rows = []
for mulu in soup.find_all(class_="mulu"):
h2 = mulu.find("h2")
if h2 is not None:
h2_title = h2.get_text() # 提取标题
for a in mulu.find(class_="box").find_all("a"):
href = a["href"] # 提取链接
box_title = a["title"] # 提取章节名
content = (h2_title, box_title, href)
rows.append(content)
存储为TXT文件:
# 一定要指定utf-8编码,否则会乱码
with open("盗墓笔记.txt", "w", encoding="utf-8") as f:
for row in rows:
f.write("n" + str(row)) # 转换为字符串,按行输出
爬取结果如下:
二:存储为json文件:
先导入json模块:
from bs4 import BeautifulSoup
import requests
import json
http请求与上相同:
url = "http://seputu.com"
user_agent = "Mozilla/5.0 (Windows NT 6.3; WOW64)"
headers = {"User_agent": user_agent}
req = requests.get(url, headers=headers)
网页解析略有不同:先将数据放在字典中,字典嵌套在列表中:
soup = BeautifulSoup(req.text, "html.parser")
content = []
_list = []
for mulu in soup.find_all(class_="mulu"):
h2 = mulu.find("h2")
if h2 is not None:
h2_title = h2.string
for a in mulu.find(class_="box").find_all("a"):
href = a["href"]
box_title = a["title"]
_list.append({"链接": href, "章节名": box_title})
content.append({"标题": h2_title, "章节列表": _list})
最后将数据存储在.json文件中:
with open("盗墓笔记.json", "w", encoding="utf-8") as fp:
# 一定要指定ensure_ascii=False,否则存储汉汉字会乱码
json.dump(content, fp=fp, indent=4, ensure_ascii=False)
看一下爬取结果如何:
假如我们在存储为json文件时没有指定ensure_ascii=False:
with open("盗墓笔记.json", "w", encoding="utf-8") as fp:
# 一定要指定ensure_ascii=False,否则存储汉汉字会乱码
json.dump(content, fp=fp, indent=4)
看一下结果会怎样:
汉字全部变成u565u4d等乱码格式。
三:将数据存储为CSV文件:
先导入CSV模块:
from bs4 import BeautifulSoup
import requests
import csv
http请求与上相同:
url = "http://seputu.com"
user_agent = "Mozilla/5.0 (Windows NT 6.3; WOW64)"
headers = {"User_agent": user_agent}
req = requests.get(url, headers=headers)
网页解析与上类似:
soup = BeautifulSoup(req.text, "html.parser")
rows = []
for mulu in soup.find_all(class_="mulu"):
h2 = mulu.find("h2")
if h2 is not None:
h2_title = h2.string
for a in mulu.find(class_="box").find_all("a"):
href = a["href"]
box_title = a["title"]
content = (h2_title, box_title, href)
rows.append(content)
存储为CSV文件:
headers_ = ("标题", "章节名", "链接")
# 打开文件时要指定newline='',否则存储为CSV时,每行数据之间都有空行
with open("盗墓笔记.csv", "w", newline='') as fp:
f_csv = csv.writer(fp)
f_csv.writerow(headers_)
f_csv.writerows(rows)
打开CSV文件,使用reader()方法:
with open("盗墓笔记.csv") as f:
f_csv = csv.reader(f)
headers_ = next(f_csv)
print(headers_)
for row in f_csv:
print(row)
爬取结果如下:
我主要遇到两个问题:
1:不知道如何在json文件中写入汉字,查阅资料后才知道在写入json文件时要指定ensure_ascii=False:
json.dump(content, fp=fp, indent=4, ensure_ascii=False)
2:我写入数据到CSV文件后,发现每行数据之间都有空行,查阅资料之后发现要在打开文件的同时指定newline='':
with open("盗墓笔记.csv", "w", newline='') as fp:
你们有遇到什么问题的话,可以互相交流。
每天学习一点点,每天进步一点点。
- 二分查找法的实现和应用汇总
- 《快学Scala》第一章 基础
- 移动端打印输出内容以及网络请求-vconsole.js
- 二分查找法的实现和应用汇总
- JavaScript前端和Java后端的AES加密和解密
- 《Spark MLlib 机器学习实战》1——读后总结
- angularjs自定义指令实现分页插件
- A+B for Input-Output Practice (V)
- 机器学习——相似度算法汇总
- 白话推荐系统——从原理到实践,还有福利赠送!
- 基于Spring Boot的Logback日志轮转配置
- Java程序员的日常—— Spring Boot单元测试
- Windows下TensorFlow安装指南(图文版)
- 20120918-双向链表类定义《数据结构与算法分析》
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android图片采样缩放功能实例代码
- Android开发中使用Intent打开第三方应用及验证可用性的方法详解
- Android 7.0开发获取存储设备信息的方法
- Android中默认系统的声音/大小修改和配置详解
- Android开发中计算器的sin、cos及tan值计算问题分析
- Android开发实现绘制淘宝收益图折线效果示例
- Android自定义View实现搜索框(SearchView)功能
- android 监听SD卡文件变化的实现代码
- Android监听手机短信的示例代码
- Android开发之图片压缩工具类完整实例
- Android6.0开发中屏幕旋转原理与流程分析
- Android中WebView的基本配置与填坑记录大全
- Android开发实现ListView异步加载数据的方法详解
- Android开发实现AlertDialog中View的控件设置监听功能分析
- 详解Android 语音播报实现方案(无SDK)