我的爬虫入门作(一)
目录
- 1. 工具
- 2. 正文
- 2.1 URL
- 2.2 思路
- 2.3 实现
- 2.3.1 获取各个章节URL
- 2.3.2 获取一章内容
- 2.3.3 写入内容
- 2.3.4 完整代码
- 3. 小结
- 3.1 html基础知识
- 3.2 Requests库方法
- 3.3 BeauifulSoup库
- 3.4 文件写入
- 3.5 各个章节URL
- 4. 参考
1. 工具
- 开发环境:Python3.7 + Visual Studio Code
- 浏览器:谷歌浏览器
- 安装Python库:requests——用来获取HTML、BeautifulSoup——用来解析HTML文档
2. 正文
2.1 URL
目标:在新笔趣阁网站上爬取烽火戏诸侯的《雪中悍刀行》(此处安利一波,烽火大大的文笔很好,天不生我李淳罡。。。。。跑偏了)。
目录页地址:http://www.xbiquge.la/0/745/
2.2 思路
- 分析目录页源码,找到保存各个章节URL的标签:右击鼠标—>选择检查(N)或者按F12,网页的源码就出来了。 要找到目录的URL,将鼠标放在其中一章目录上右击鼠标,源码就会跳到对应的内容那里。可见各章节的URL存放在属性id=’'list"的div标签内,只需找到对应属性的div,再将其内包含的所有a标签找出,就是找齐所有章节的URL了。
- 分析章节页内容:在内容(正文)上右击鼠标—>检查,跳到源码对应的内容。发现内容被存放在属性id="content"的div标签上,所以需要找到相应的div标签,再输出内容。
- 总体思路:在目录页获取各个章节的URL—>通过各个章节的URL遍历各个章节的内容—>写入文本文件(txt)里面
2.3 实现
2.3.1 获取各个章节URL
def __get_Link_chapter(self):'''在目录页获得各个章节的url.解析目录页,通过属性找到存放各个章节url的div标签,获取各个章节的url并且返回'''# 当请求发生异常:连接或者超时错误,等待1S再尝试for try_counter in range(10):try:req_lp = requests.get(self.__url_lp, timeout=10)breakexcept ConnectionError:print('尝试获取目录页ConnectionError:%d' % (try_counter+1))except TimeoutError:print('尝试获取目录页TimeoutError:%d' % (try_counter+1))except:print('尝试获取目录页OtherError:%d' % (try_counter+1))time.sleep(1)if try_counter >= 9:print('获取目录页失败')returnelse:try:req_lp.encoding = req_lp.apparent_encoding# 建立BeautifulSoup对象,指定解析器lxmlbs_lp = BeautifulSoup(req_lp.text, 'lxml')# 找到所有对应属性的div标签div_list = bs_lp.find_all('div', attrs=self.__attrs_div_lp)# 找到所有的a标签link_chapter = []for div in div_list:link_chapter += div.find_all('a')return link_chapterexcept TypeError:print('目录页解析异常:TypeError')returnexcept:print('目录页解析异常:OtherError')return
2.3.2 获取一章内容
def __get_content_chapter(self, link):'''获取章节内容.:param link:在目录页解析后得到的a标签内含章节名和url'''name_chapter = link.stringurl_chapter = self.__url_ws + link['href'] # 拼接得到章节页url# 在链接和读取过程中,出现异常的处理方式# 这里出现异常的话循环10次,等待1S重新读取for try_counter in range(10):try:# 超时设置为10Sreq_ct = requests.get(url_chapter, timeout=10)breakexcept ConnectionError:print('尝试获取章节链接:ConnectionError%d' % (try_counter+1))except TimeoutError:print('尝试获取章节链接:TimeoutError%d' % (try_counter+1))except:print('尝试获取章节链接:OtherError%d' % (try_counter+1))time.sleep(1)if try_counter >= 9:print('获取链接失败:'+name_chapter)return name_chapter+'\n\n'else:try:req_ct.encoding = self.__encode# 建立BeautifulSoup对象bs_ct = BeautifulSoup(req_ct.text, 'lxml')# 将找到的div内容转换成文本格式,# 并且将里面的 (不间断空格)替换成空格# 将br标签替换成换行符content = bs_ct.find('div', attrs=self.__attrs_div_ct)content = str(content).replace('<br/>','\n').replace('\xa0',' ')content = BeautifulSoup(content,'lxml').get_text()return name_chapter + '\n\n' + content + '\n\n'except TypeError:print('章节页解析异常:TypeError '+name_chapter)return name_chapter+'\n\n'except:print('章节页解析异常:OtherError '+name_chapter)return name_chapter+'\n\n'
2.3.3 写入内容
def write(self, path_save):'''写下载的文件到指定路径.:param path_save:指定的保存路径'''# 在指定的文件夹路路径之下新建与书名同名的文本文件path_save = path_save + '\\' + self.__name + '.txt'# 获取各个章节的URLlink_chapter = self.__get_Link_chapter()if link_chapter is None:passelse:# 打开文件with open(path_save, 'w+', encoding=self.__encode) as file:for chapter, link in enumerate(link_chapter):# 获取章节内容content_chapter = self.__get_content_chapter(link)file.write(content_chapter)sys.stdout.write('下载进度:%.1f%%' % float(chapter/len(link_chapter)*100)+'\r')print('<<'+self.__name+'>>下载完成')
2.3.4 完整代码
from bs4 import BeautifulSoup
import requests
import time
import sysclass fiction():def __init__(self, name, url_ws, url_lp, encode, attrs_div_lp={}, attrs_div_ct={}):self.__name = name # 名字self.__url_ws = url_ws # 网站urlself.__url_lp = url_lp # 链接(目录)页的urlself.__attrs_div_lp = attrs_div_lp # 链接(目录页)存放各个章节链接的div标签属性self.__attrs_div_ct = attrs_div_ct # 章节页存放内容的div标签属性self.__encode = encode # 指定编码格式def Update(self, name, url_ws, url_lp, encode, attrs_div_lp={}, attrs_div_ct={}):'''重置参数必须同时重置所有参数,否则可能出现错误'''self.__name = name # 名字self.__url_ws = url_ws # 网站urlself.__url_lp = url_lp # 链接(目录)页的urlself.__attrs_div_lp = attrs_div_lp # 链接(目录页)存放各个章节链接的div标签属性self.__attrs_div_ct = attrs_div_ct # 章节页存放内容的div标签属性self.__encode = encodedef __get_Link_chapter(self):'''在目录页获得各个章节的url.解析目录页,通过属性找到存放各个章节url的div标签,获取各个章节的url并且返回'''# 当请求发生异常:连接或者超时错误,等待1S再尝试for try_counter in range(10):try:req_lp = requests.get(self.__url_lp, timeout=10)breakexcept ConnectionError:print('尝试获取目录页ConnectionError:%d' % (try_counter+1))except TimeoutError:print('尝试获取目录页TimeoutError:%d' % (try_counter+1))except:print('尝试获取目录页OtherError:%d' % (try_counter+1))time.sleep(1)if try_counter >= 9:print('获取目录页失败')returnelse:try:req_lp.encoding = req_lp.apparent_encoding# 建立BeautifulSoup对象,指定解析器lxmlbs_lp = BeautifulSoup(req_lp.text, 'lxml')# 找到所有对应属性的div标签div_list = bs_lp.find_all('div', attrs=self.__attrs_div_lp)# 找到所有的a标签link_chapter = []for div in div_list:link_chapter += div.find_all('a')return link_chapterexcept TypeError:print('目录页解析异常:TypeError')returnexcept:print('目录页解析异常:OtherError')returndef __get_content_chapter(self, link):'''获取章节内容.:param link:在目录页解析后得到的a标签内含章节名和url'''name_chapter = link.stringurl_chapter = self.__url_ws + link['href'] # 拼接得到章节页url# 在链接和读取过程中,出现异常的处理方式# 这里出现异常的话循环10次,等待1S重新读取for try_counter in range(10):try:# 超时设置为10Sreq_ct = requests.get(url_chapter, timeout=10)breakexcept ConnectionError:print('尝试获取章节链接:ConnectionError%d' % (try_counter+1))except TimeoutError:print('尝试获取章节链接:TimeoutError%d' % (try_counter+1))except:print('尝试获取章节链接:OtherError%d' % (try_counter+1))time.sleep(1)if try_counter >= 9:print('获取链接失败:'+name_chapter)return name_chapter+'\n\n'else:try:req_ct.encoding = self.__encode# 建立BeautifulSoup对象bs_ct = BeautifulSoup(req_ct.text, 'lxml')# 将找到的div内容转换成文本格式,# 并且将里面的 (不间断空格)替换成空格# 将br标签换成换行符content = bs_ct.find('div', attrs=self.__attrs_div_ct)content = str(content).replace('<br/>','\n').replace('\xa0',' ')content = BeautifulSoup(content,'lxml').get_text()return name_chapter + '\n\n' + content + '\n\n'except TypeError:print('章节页解析异常:TypeError '+name_chapter)return name_chapter+'\n\n'except:print('章节页解析异常:OtherError '+name_chapter)return name_chapter+'\n\n'def write(self, path_save):'''写下载的文件到指定路径.:param path_save:指定的保存路径'''# 在指定的文件夹路路径之下新建与书名同名的文本文件path_save = path_save + '\\' + self.__name + '.txt'# 获取各个章节的URLlink_chapter = self.__get_Link_chapter()if link_chapter is None:passelse:# 打开文件with open(path_save, 'w+', encoding=self.__encode) as file:for chapter, link in enumerate(link_chapter):# 获取章节内容content_chapter = self.__get_content_chapter(link)file.write(content_chapter)sys.stdout.write('下载进度:%.1f%%' % float(chapter/len(link_chapter)*100)+'\r')print('<<'+self.__name+'>>下载完成')if __name__ == '__main__':start = time.time()f = fiction(name='雪中悍刀行',url_ws='http://www.xbiquge.la',url_lp='http://www.xbiquge.la/0/745/',attrs_div_lp={'id': 'list'},attrs_div_ct={'id': 'content'},encode='utf-8')f.write(r'C:\Users\HP\Desktop\pytxt')stop = time.time()print('用时:%ds' % (stop-start))
3. 小结
3.1 html基础知识
html基础知识:菜鸟教程——HTML教程
3.2 Requests库方法
- get():获取服务器响应的内容。注意:最好设置超时时间,否者如果服务器无响应则一直会发送请求,程序就会一直卡在那个地方,而且不会报异常或者错误。
- 关于编码问题:最好是指定编码方式,根据Requests猜测的编码可能不准,后面写入文本的时候可能会发生异常。具体的分析可以参考知乎
html在源码head部分的charset就指定了编码,有时候说明的编码和实际使用的编码不一致,此时使用Response.apparent_encoding指定编码。
req_lp.encoding = req_lp.apparent_encoding
3. Requests库更多更详细可以参考官方文档:快速上手、高级用法、开发接口
3.3 BeauifulSoup库
- 建立BeauifulSoup对象:
bs_lp = BeautifulSoup(req_lp.text, 'lxml')
第一个参数时需要解析的HTML文档,第二个参数时指定的文档解析器
2. find_all()方法:寻找当前tag标签下符合过滤条件的所有标签,返回一个bs4.element.ResultSet类型,其实可以像列表形式使用。
3. 编码:使用BeautifulSoup之后,无论原来的HTML文档是gbk编码还是utf-8编码亦或是其他编码,全都会转成Unicode编码,可能是因为Unicode编码兼容所有的语言吧。
3.4 文件写入
Python文件操作:菜鸟教程——Python3 File(文件) 方法
3.5 各个章节URL
目录页的各个章节的URL是不完整的,需拼接上网站的URL才算是完整的URL。
url_chapter = self.__url_ws + link['href'] # 拼接得到章节页url
4. 参考
- Python3网络爬虫快速入门实战解析
- python3爬虫中文乱码问题求解?(beautifulsoup4)
第一次修改:将br标签换成换行符
我的爬虫入门作(一)相关推荐
- python很全的爬虫入门教程
python很全的爬虫入门教程 一.爬虫前的准备工作 首先,我们要知道什么是爬虫 1.什么是网络爬虫? 网络爬虫是一种按照一定的规则,自动的抓取万维网信息的程序或者脚本.另外一些不常使用的名字还有蚂蚁 ...
- 爬虫入门学习(八)模拟登录丁香园论坛爬取用户信息
爬虫入门学习(八)实战大项目模拟登录丁香园爬取信息 1 目标 2 思路 3 主要的技术点 3.1 模拟登录 3.2 抓取用户个人主页 4 完整代码 5 项目后期拓展 1 目标 模拟登录丁香园,并抓取页 ...
- Python 爬虫入门教程——社团授课型
Python爬虫入门教程 基础知识 什么是HTML.CSS.JavaScript 网页往往采用html+css+js开发,html是一门标记语言 如下: <!- 将下面这句话放入html文件中, ...
- Python爬虫入门2(实战)
文章目录 13.B站直播间弹幕爬取 代码: 运行结果: 14.xpath解析爬虫 入门: lxml安装: 基本格式: 15.xpath入门讲解 材料: py代码: 运行结果: 技巧: 16.xpath ...
- python爬虫入门教程(二):开始一个简单的爬虫
2019/10/28更新 使用Python3,而不再是Python2 转载请注明出处:https://blog.csdn.net/aaronjny/article/details/77945329 爬 ...
- Python爬虫入门教程02:小说爬取
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理. 前文 01.python爬虫入门教程01:豆瓣Top电影爬取 基本开发环境 Python 3 ...
- python爬虫入门教程--优雅的HTTP库requests(二)
requests 实现了 HTTP 协议中绝大部分功能,它提供的功能包括 Keep-Alive.连接池.Cookie持久化.内容自动解压.HTTP代理.SSL认证等很多特性,下面这篇文章主要给大家介绍 ...
- python爬虫入门教程--快速理解HTTP协议(一)
http协议是互联网里面最重要,最基础的协议之一,我们的爬虫需要经常和http协议打交道.下面这篇文章主要给大家介绍了关于python爬虫入门之快速理解HTTP协议的相关资料,文中介绍的非常详细,需要 ...
- 爬虫入门到精通-HTTP协议的讲解
HTTP协议的讲解 本文章属于爬虫入门到精通系统教程第三讲 什么是HTTP协议? 引用自维基百科 超文本传输协议(英文:HyperText Transfer Protocol,缩写:HTTP)是互联网 ...
最新文章
- python opengl 入门
- oracle中更改列明和更改显示列长度
- java 生产者消费者_基于JAVA的生产者消费者问题
- unity3d连接数据库
- 文本格式化标签(HTML)
- 在lua中优雅的操作日期和时间
- web前端开发之微信小程序
- 编译原理 自底向上语法分析
- asp.net学习心得总结
- php trying to get,php 做微信认证登陆 返回错误 Trying to get property of non-object
- java项目视频22套
- 【题解】[Swerc2008]First Knight
- 模拟电子电路基础——放大器理解与梳理
- ORA-00937:不是单组分组函数 ORA-22818:这里不允许出现子查询表达式
- 受到人工智能发展的影响的,主要包括哪些行业?
- element el-dialog样式修改
- AMD GPU的断点指令
- 15天精读掌握《高德纳:具体数学》 第3天 2019.5.29
- 软件测试入门简单么?入行后如何做职业规划
- c语言编译数学公式器,公式编辑器 - 数学公式在线编辑器 - MathEditor