学习python第一天,第一次学习脚本语言还不习惯,不能看变量类型好不爽,没有括号好不爽,果然java和scala写多了吗
想写个小程序练练手,想起看小说广告很多很不方便,就写了个爬虫程序用于爬取网上的小说。毕竟兴趣是第一生产力!
小说来源,新笔趣阁。代码很短
以下代码使用的是python3.6,编辑器用的Pycharm。
用到了BeautifulSoup库。此库用于解析HTML文件。关于此库这次只是粗略使用,很多都是摸索和google,待浏览完使用手册和写更多的项目后再开文章进行整理
关于此库的安装用PIP即可,Pycharm下可以选择File -> Setting -> Project pythonlearn -> Project Interpreter的右边加号进行搜索添加
首先我随便搜索了本小说,打开章节网页https://www.xxbiquge.com/12_12914/,右键查看网页源代码,看了一下哇那么简单!那今天就爬你啦!笔者用的浏览器为Google Chrome
于是首先百度了下怎么用python3拉取html下来,利用lxml进行解析
如果没有安装lxml则会报错!安装lxml参考BeautifulSoup
1 import urllib.request 2 from bs4 import BeautifulSoup 3 url = \'https://www.xxbiquge.com/12_12914/\' 4 res = urllib.request.urlopen(url) 5 html = res.read().decode(\'utf-8\') 6 soup = BeautifulSoup(html,\'lxml\') 7 print(soup)
以上是代码,可以看到直接打出了整个HTML里的内容。
然后我想提取出里面关于章节的超链接,我就需要解析这个HTML。于是百度了下。BeautifulSoup决定就是你了,去吧!
#找到所以标签为a的内容 l = soup.find_all(\'a\')
利用上面的代码找到里面所有标签为a的内容,里面包含我们所需要的链接和其他的一些干扰信息,因此用正则写了个简单的过滤。pyhton3要用正则需要import re
其中n.string为提取标签中的内容
n.get(\'href\')为提取当中链接的值
以上内容理解可能有误,待笔者仔细研究后详细说明
pattern = re.compile(\'第.+章\') for n in soup.find_all(\'a\'): if(pattern.match(n.string)): print(n.get(\'href\')) print(n.string)
过滤完发现其中的提取的链接只有后面一部分,因此需要自己补上前面的
然后再依次浏览每个章节的链接,从中提取章节内容,很简单以下不再继续阐述
直接贴出所有代码
import urllib.request from bs4 import BeautifulSoup import re #将字符串写入文本中,这里要指定encoding格式,不然会报错。‘a’表示继续写入,不覆盖之前的内容
#关于with的语法笔者会研究后再整理
def writeFile(str,file): if file: with open(file, \'a\', encoding=\'utf-8\') as f: f.write(str) else: with open(file, \'a\', encoding=\'utf-8\') as f: f.write(str) #主函数 #输出的txt路径。笔者选择了当前目录下 outputTxtFile = \'寒门崛起\' #章节目录的网址 contentUrl = \'https://www.xxbiquge.com/12_12914/\' #网址前缀 url = \'https://www.xxbiquge.com\' res = urllib.request.urlopen(contentUrl) html = res.read().decode(\'utf-8\') soup = BeautifulSoup(html,\'lxml\') pattern = re.compile(\'第.+章\') for chapter in soup.find_all(\'a\'): if(pattern.match(chapter.string)): readRes = urllib.request.urlopen(url + chapter.get(\'href\')) readHtml = readRes.read().decode(\'utf-8\') readSoup = BeautifulSoup(readHtml, \'lxml\') writeFile(chapter.string+\'\n\',outputTxtFile) for k in readSoup.find_all(id = \'content\'): str=\'\' for line in k: if not (line.string is None): str = str + line.string + \'\n\'
for line in k.stripped_strings:
str = str + line + \'\n\'
writeFile(str,outputTxtFile)
print(\'导入 \'+chapter.string+\' 完成\')
以上代码还有两个BUG
第一是导出的文件前面有四个空格,很奇怪,怎么都去不掉,笔者继续研究下
在研读过BeautifulSoup使用手册后,BUG已经解决了
可用.stripped_string提取中某个tag下所有文本信息并去除空格(tag我暂且理解为一个节点),代码也做了修改
果然说明手册才是王道,抽空继续学习。
这个是手册的中文地址https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html
第二是他会导出最新章节放在前面没有过滤掉,这个笔者懒得改了,毕竟不是生产项目只为学习