最近,我朋友说我做的爬虫不行,比如那个爬取全站的小说,你无法指定,他只会一直的爬,他们说爬下来的小说都不是他们想要的,我就想,能不能搞一个智能爬虫,只要你输入想要的小说,它就自动给你搜索,然后把符合条件的几本小说的详细信息给你,然后让你自己选择.
确定了思路后,话不多说,直接刚上去。
要搞智能爬虫,首先该搞的,就是搜索功能,当然,凭我自己是不可能搞出来的,得借助网站!]
正在想的时候呢,却发现笔趣阁自带搜索功能!天助我也!
诶,规律是如此简单,那不就可以了吗,直接询问要查的小说,然后拼接URL啊
话不多说,上代码
def workOn(self):
init(autoreset=True)
# 搜索的内容
print("************************************本作品作者QQ:1686079252*************************************")
time.sleep(1)
Search_content = input("请输入你要下载的小说:")
if Search_content.isdigit() == True: # 检测输入的是否全是数字
while True:
Search_content = input("格式有误,请再次输入你要下载的小说:") # 重复检测输入的内容是否全是数字
if Search_content.isdigit() == False:
break
else:
pass
else:
while True:
print(Fore.RED + "搜索中....")
time.sleep(2)
url = 'http://www.tianxiabachang.cn/cse/search?q=' + Search_content + '&s=' # 拼接url
response = requests.get(url,headers=self.headers).content.decode() # 查询网页的源代码
req = etree.HTML(response)
首先,先判断用户输入的是否全是数字,然后就是拼接URL啦,也挺简单的
源码是拿到了,可是剩下的,拿到详细信息呢?这时,就用到了我们的xpath了
这样,我们书名就匹配出来了
最新章节的
作者的
现在,我们就在python里写一下`
req = etree.HTML(response)
title_of_the_search = req.xpath('//*[@id="main"]/div/ul/li/span[@class="s2"]/a/text()') # 匹配出书名
Latest_chapter = req.xpath('//*[@id="main"]/div/ul/li/span[@class="s3"]/a/text()') # 匹配出最新章节
author = req.xpath('//*[@id="main"]/div/ul/li/span[@class="s4"]/text()') # 匹配出作者
好的,全部匹配出来啦,接下来,就是做一些繁琐的事情了
Number_of_contents = len(title_of_the_search)
这是为了让别人用起来更舒服
还有判断是否有这本小说的
if Number_of_contents == 0:
Search_content = input(Fore.WHITE + "未搜索到相关内容,请重新输入:")
Number_of_contents = len(title_of_the_search)
else:
break
当当当当,搜索功能就做好啦
接下来,就是服务功能啦
print("找到了%d个相关的内容" % Number_of_contents)
time.sleep(2)
for i in range(0,len(title_of_the_search)):
self.o = self.o + 1
print(Fore.LIGHTRED_EX + '序号:%s' % self.o)
print(Fore.LIGHTYELLOW_EX + '书名:%s' % title_of_the_search[i])
print(Fore.LIGHTMAGENTA_EX + "最新章节:%s" % Latest_chapter[i])
print(Fore.LIGHTMAGENTA_EX + '作者:%s\n\n' % author[i])
time.sleep(1)
while True:
crawl_book = int(input("请问你要下载哪本书(记得填序号哦):"))
if crawl_book <= len(title_of_the_search):
print(Fore.LIGHTMAGENTA_EX + "正在查找.....")
break
else:
crawl_book = print("没有这本书哦,请重新输入")
time.sleep(1)
当当当当,这个服务绝对是五星服务!
还剩解析部分了
最重要的,就是找出URL的后缀
本来我是卡在这一关的,因为奈何我技术不行,弄不来高级的。可是后来,忽然发现了一个重要的信息
我惊奇的发现,只要改动这个li[]里面的数,获得的链接也是不同
第一行的url对应il就是2,第二行对应的就是3,那不就可以了吗
ol = crawl_book + 1
books_web_site = etree.HTML(response)
books_web_site_xpath = books_web_site.xpath('//*[@id="main"]/div[1]/ul/li[%s]/span[2]/a/@href ' % str(ol))
if bool(books_web_site_xpath) == False:
print('搜索失败')
self.workOn()
让用户输入小说的序号,然后定义一个变量ol,它的值就是用户输入的序号再加上1,这样正好就得到了每一本书的URL后缀了,那么接下来不就简单了吗?直接把url找出,然后再用正则,xpath,css来提炼出正文内容了,直接上代码
else:
print(Fore.RED + '搜索成功!')
url_one_book = self.Homepage + books_web_site_xpath[0] # 得到书的url
one_book_res = requests.get(url_one_book,headers=self.headers).content.decode() # 解析
one_book_res_xpath = etree.HTML(one_book_res)
book_name = one_book_res_xpath.xpath('//div[@id="maininfo"]/div/h1')[0].text + ".txt" # 书的名字
one_book_res = re.findall('正文</dt>(.*?)</dl>',one_book_res,re.S) # 匹配正文
htmls = parsel.Selector(one_book_res[0])
html_gen = htmls.css(' dd a::attr(href)').extract() # 每一章的网址后缀
for Html in html_gen:
url_book = self.Homepage + Html
url_book_res = requests.get(url_book,headers=self.headers).content.decode()
# 标题
reo = etree.HTML(url_book_res)
rrr = reo.xpath('//div[@class="bookname"]/h1')[0].text
# 正文内容
req = re.findall('<div id="content">(.*?)<table style="width:100%;',url_book_res, re.S)
req = re.sub('<br.*?>| |</br>|<div id="content"> |<table style="width:100%|</div>','', req[0])
req = req.replace('\n','')
rel = rrr + "\n" + req # 完整的正文
self.writePage(book_name,rel,rrr)
l = input("爬取玩了哦,小说就在跟程序同一个文件夹里,按回车退出程序,输入继续将再次为你爬取")
if l == "继续":
ll = BiqugeSpyder()
ll.workOn()
else:
print("拜拜")
sys.exit()
if __name__ == '__main__':
Spyder = BiqugeSpyder()
Spyder.workOn()
其实这个智能爬虫就是搜索功能有点难度,其他的其实就不难了,哎,考虑了一下,直接开源!给大家做参考
import requests,time,re,parsel,sys
from lxml import etree
from colorama import init,Fore,
class BiqugeSpyder:
def __init__(self):
self.o = 0 # 这个o是为了xpath表达式
self.Homepage = 'http://www.tianxiabachang.cn'
self.headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"}
def writePage(self,book_name,rel,rrr):
with open(book_name, "a", encoding="utf-8") as f:
f.write(rel)
print("打印成功!%s" % rrr)
def workOn(self):
init(autoreset=True)
# 搜索的内容
print("************************************本作品作者QQ:1686079252*************************************")
time.sleep(1)
Search_content = input("请输入你要下载的小说:")
if Search_content.isdigit() == True: # 检测输入的是否全是数字
while True:
Search_content = input("格式有误,请再次输入你要下载的小说:") # 重复检测输入的内容是否全是数字
if Search_content.isdigit() == False:
break
else:
pass
else:
while True:
print(Fore.RED + "搜索中....")
time.sleep(2)
url = 'http://www.tianxiabachang.cn/cse/search?q=' + Search_content + '&s=' # 拼接url
response = requests.get(url,headers=self.headers).content.decode() # 查询网页的源代码
req = etree.HTML(response)
title_of_the_search = req.xpath('//*[@id="main"]/div/ul/li/span[@class="s2"]/a/text()') # 匹配出书名
Latest_chapter = req.xpath('//*[@id="main"]/div/ul/li/span[@class="s3"]/a/text()') # 匹配出最新章节
author = req.xpath('//*[@id="main"]/div/ul/li/span[@class="s4"]/text()') # 匹配出作者
Number_of_contents = len(title_of_the_search)
if Number_of_contents == 0:
Search_content = input(Fore.WHITE + "未搜索到相关内容,请重新输入:")
Number_of_contents = len(title_of_the_search)
else:
break
print("找到了%d个相关的内容" % Number_of_contents)
time.sleep(2)
for i in range(0,len(title_of_the_search)):
self.o = self.o + 1
print(Fore.LIGHTRED_EX + '序号:%s' % self.o)
print(Fore.LIGHTYELLOW_EX + '书名:%s' % title_of_the_search[i])
print(Fore.LIGHTMAGENTA_EX + "最新章节:%s" % Latest_chapter[i])
print(Fore.LIGHTMAGENTA_EX + '作者:%s\n\n' % author[i])
time.sleep(1)
while True:
print(Fore.LIGHTBLACK_EX + "傻逼,看不见吧")
crawl_book = int(input("请问你要下载哪本书(记得填序号哦):"))
if crawl_book <= len(title_of_the_search):
print(Fore.LIGHTMAGENTA_EX + "正在查找.....")
break
else:
crawl_book = print("没有这本书哦,请重新输入")
time.sleep(1)
ol = crawl_book + 1
books_web_site = etree.HTML(response)
books_web_site_xpath = books_web_site.xpath('//*[@id="main"]/div[1]/ul/li[%s]/span[2]/a/@href ' % str(ol))
if bool(books_web_site_xpath) == False:
print('搜索失败')
self.workOn()
else:
print(Fore.RED + '搜索成功!')
url_one_book = self.Homepage + books_web_site_xpath[0] # 得到书的url
one_book_res = requests.get(url_one_book,headers=self.headers).content.decode() # 解析
one_book_res_xpath = etree.HTML(one_book_res)
book_name = one_book_res_xpath.xpath('//div[@id="maininfo"]/div/h1')[0].text + ".txt" # 书的名字
one_book_res = re.findall('正文</dt>(.*?)</dl>',one_book_res,re.S) # 匹配正文
htmls = parsel.Selector(one_book_res[0])
html_gen = htmls.css(' dd a::attr(href)').extract() # 每一章的网址后缀
for Html in html_gen:
url_book = self.Homepage + Html
url_book_res = requests.get(url_book,headers=self.headers).content.decode()
# 标题
reo = etree.HTML(url_book_res)
rrr = reo.xpath('//div[@class="bookname"]/h1')[0].text
# 正文内容
req = re.findall('<div id="content">(.*?)<table style="width:100%;',url_book_res, re.S)
req = re.sub('<br.*?>| |</br>|<div id="content"> |<table style="width:100%|</div>','', req[0])
req = req.replace('\n','')
rel = rrr + "\n" + req # 完整的正文
self.writePage(book_name,rel,rrr)
l = input("爬取玩了哦,小说就在跟程序同一个文件夹里,按回车退出程序,输入继续将再次为你爬取")
if l == "继续":
ll = BiqugeSpyder()
ll.workOn()
else:
print("拜拜")
sys.exit()
if __name__ == '__main__':
Spyder = BiqugeSpyder()
Spyder.workOn()
这就是完整的代码啦,(**不要玩的太嗨,被笔趣阁知道了就完啦 **)