Python作为爬虫工具简单方便,这里举个我爬取笔趣阁小说的例子。
所需模块
BeautifulSoup、lxml、urllib
这个的作用是通过url读取html文档以及解析,安装方法可以参考: Python3安装beautifulsoup4和lxml
流程
1、分析笔趣阁https://www.biqiuge.com小说url的结构
通过分析可以知道,笔趣阁每本小说的链接为:https://www.biqiuge.com/book/id/
id为数字,从1开始,比如第一篇https://www.biqiuge.com/book/1/ 以发现是龙符。以后每本小说由数字加上去。
2、用urllib工具访问url返回html页面内容
访问内容我们可以知道,并没有进行任何异步加载,并且是全部章节都显示出来。如果是异步的话,可能需要模拟浏览器,这个以后有时间说明。
3、用BeautifulSoup、lxml解析小说页面,获取所有章节列表以及小说标题
这一步用BeautifulSoup工具来很简单。举个例子如下,有一个html字符串,然后转变为BeautifulSoup对象,然后很方便的解析出标签内容。
soup_texts = BeautifulSoup(html, 'lxml')
texts = soup_texts.find_all(class_="info")
soup_text = BeautifulSoup(str(texts),"lxml")
title = soup_text.find_all("h2")
title=title[0].string
spans = soup_text.find_all("span")
4、用io保存为txt小说
保存之前,这里需要对
换行符都替换成”\n”,因为在txt中,这个才是换行符。
所有代码
#!/usr/bin/env python
# -*- coding:utf-8 -*-
##导入爬取模块
from bs4 import BeautifulSoup
from urllib import request
##根据url获取response
def getResponse(url):
#url请求对象Request是一个类
#如果不加上下面的这行出现会出现urllib2.HTTPError: HTTP Error 403: Forbidden错误 #主要是由于该网站禁止爬虫导致的,可以在请求加上头信息,伪装成浏览器访问User-Agent,具体的信息可以通过火狐的FireBug插件查询 headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0'} req = urllib.request.Request(url=chaper_url, headers=headers)
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0'}
url_request = request.Request(url=url, headers=headers)
#print(url_request)
#print(url_request.data)
try:
url_response = request.urlopen(url_request)
except Exception as e:
url_response="error"
"""
geturl():返回 full_url地址
info(): 返回页面的元(Html的meta标签)信息
<meta>:可提供有关页面的元信息(meta-information),比如针对搜索引擎和更新频度的描述和关键词。
getcode(): 返回响应的HTTP状态代码
100-199 用于指定客户端应相应的某些动作。
200-299 用于表示请求成功。
300-399 用于已经移动的文件并且常被包含在定位头信息中指定新的地址信息。
400-499 用于指出客户端的错误。
500-599 用于支持服务器错误。
read(): 读取网页内容,注意解码方式(避免中文和utf-8之间转化出现乱码)
"""
return url_response #返回这个对象
#获取这一本书
def getNewBook(sort):
infos = getAllChaptersAndInfo("https://www.biqiuge.com/book/"+str(sort)+"/")
if(infos=="error"):
print("停止")
return "error"
#保存书本信息
books = infos[1]
username=books["username"]
status=books["status"]
title=books["title"]
username = username[3:]
status = status[3:]
if status=="完结":
dealChapters(infos[0],title,username,sort)
else:
return
#获取章节和内容
def getAllChaptersAndInfo(url):
http_reponse = getResponse(url)
if(http_reponse=="error"):
return "error"
html = http_reponse.read()
html = html.decode("gbk",errors="ignore")
list = getChapters(html)
info = getInfo(html)
return [list,info]
#解析html获取章节列表
def getChapters(html):
i = html.find("正文卷")
html=html[i:]
soup_texts = BeautifulSoup(html, 'lxml')
texts = soup_texts.find_all("dd")
soup_text = BeautifulSoup(str(texts),"lxml")
#获得章节列表
html = soup_text.find_all("a")
return html;
def getInfo(html):
soup_texts = BeautifulSoup(html, 'lxml')
texts = soup_texts.find_all(class_="info")
soup_text = BeautifulSoup(str(texts),"lxml")
title = soup_text.find_all("h2")
title=title[0].string
spans = soup_text.find_all("span")
username = spans[0].string
status = spans[2].string
info={"username":username,"title":title,"status":status}
return info
#获取文章列表
def dealChapters(list,booktitle,username,sort):
size = len(list)
print("这次获取的章节数:"+str(size))
book = str(sort)+"-"+booktitle+"-"+username+".txt"
fo = open("./txt/"+book,"a+")
for index in range(size):
#这里是从0开始,但是章节要+1,当章节大于最大章节才开始下载
d = list[index]
title = d.string
print("正在下载:"+title.encode('gbk', 'ignore').decode('gbk'))
href = "https://www.biqiuge.com"+d['href']
text = getChapter(href).replace("\xa0","").replace("<br/>","\n")
try:
fo.write(title+"\n"+text+"\n")
except Exception as e:
print("有异常")
fo.write(title,"有异常")
continue
print("下载完成")
fo.close()
#获取文章内容
def getChapter(url):
http_reponse = getResponse(url)
html = http_reponse.read()
html = html.decode("gbk",errors="ignore")
soup_texts = BeautifulSoup(html, 'lxml')
texts = soup_texts.find_all(id='content', class_='showtxt')
text = str(texts[0]).strip().replace("\r","").replace("\n","")
start = text.find("\">")
end = text.find("https://www")
text=text[start+2:end]
#print(text.encode('gbk', 'ignore').decode('gbk'));
return text
fo = open("sort","r+")
try:
sort = fo.readline()
sort = int(sort.strip().replace("\n",""))
print("已经下载的章节是:"+str(sort))
for i in range(sort,100000):
index= i+1
fo.seek(0)
fo.truncate()
fo.write(str(index))
getNewBook(index)
except Exception as e:
print("下载发生异常,暂停"+str(e))
fo.close()
finally:
fo.close()
上面还记录了加载的小说id,这样子,下次启动就可以直接从最新的id开始,如果只是想要加载某一本小说的话,只需要执行getNewBook(index)
即可,index为小说id,这个根据小说名称去笔趣阁搜索,然后链接就可以看到。我这个代码还判断了小说是否是完本小说,毕竟完本小说才方便。
转载请注明来源。