当前位置:   article > 正文

python bs4+多线程爬取一整部小说(小白第一篇博客)_多线程爬取小说

多线程爬取小说

今天与大家分享一下,学了bs4和多线程之后的第一次实践。今天爬取的目标是纵横中文网的小说《元尊》。
目标链接

bs4,正则表达式,xpath是初学者易学易上手的三大神器,其中re的速度最快,xpath其次,bs4最后,bs4和xpath需要对html标签有一定的了解,这个可以去菜鸟教程了解一下,上手很快。多线程,说话我学了一个星期,还是没学太明白,自学的就是这样,没有人授业解惑,一个小问题自己百度可能一两个小时也没解决。bs4大家可以去官方文档学习,今天用到的都是非常简单的,看下代码中的注释应该可以理解,我就不上bs4的教程了,好了步入今天的正题。

网页分析

在这里插入图片描述说是爬取一整部其实是大概前90多章,因为后面的都是花钱的,这是正版网站。爬取盗版网站可以,for循环改下数字就ok了。
在这里插入图片描述
在这里插入图片描述
谷歌浏览器F12->All->左边选择第一个->response往下拉可以看到小说正文在一个class="content"的div标签的子标签p标签里。第二张图我们可以看到标题在一个class="title_txtbox"的div标签里。

上代码,先爬取一章

import requests
url = 'http://book.zongheng.com/chapter/685640/38883752.html'
#UA在上图的Headers里面下拉可以找到复制粘贴即可
headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.108 Safari/537.36'
        }
response = requests.get(url,headers = headers)
#第一个参数是response返回的text,第二个是使用html解析
soup = BeautifulSoup(response.text,'html.parser')
#findAll方法是找到所有符合要求的内容,返回的是一个列表
div = soup.findAll("div",class_ = "content")
#找到每一章的title
title = soup.findAll("div",class_ = "title_txtbox")
#strip方法可以去掉首尾特定的字符,所以就确定了标题
souptitle = BeautifulSoup(str(title),'html.parser').text.strip("[]")
#最终要写入文件的小说内容
#因为findAll返回的是列表,bs4只能解析str所以强转一下
#得到是一行结束的小说内容,五哦一我们用replace以一个句号为一段落
souptext = BeautifulSoup(str(div),'html.parser').text.strip("[]").replace("。","。\n")
#把我们爬取到的内容写入文件就大功告成啦!
f = open("C:/f.txt","a")
f.write(str(souptitle)+'\r')
f.write(str(souptext)+'\r')
f.close()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

我们写入到text的小说可以添加到小说软件中,可以识别并有序排版
在这里插入图片描述

爬取全部!

分析:
在这里插入图片描述
在这里插入图片描述
比较第一张图片和第二张图片的url可以看出,不同章节的url只是最后的那一串数字不同,通常这种情况下,这些东西都在网页的html代码中。
在这里插入图片描述
在第一章的网页源代码中我们可以看到nextchaterid=“38885173”正是我们要找的第二章的url中的末尾的那一串数字,这样我们可以通过bs4爬取到这一串数字,然后就可以拼接第二章的url,以此类推所有的章节的url都可以得到,整本小说也就爬取到了

def main():
	#第一章小说的末尾数字串
    a = ['38883752']
    for i in range(90):
        url = "http://book.zongheng.com/chapter/685640/{}.html".format(a[i])
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.108 Safari/537.36'
        }
        response = requests.get(url, headers=headers)
        soup = BeautifulSoup(response.text, 'html.parser')
        # 小说内容在div标签里
        nextpage = soup.body['nextchapterid']
        #爬取90章小说的末尾数字串,放到列表中
        a.append(nextpage)
    return a
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

90章小说+多线程,有很多需要优化的地方,望留言更改

import threading
import requests
from bs4 import BeautifulSoup
import time
import sys
#多线程
class myThreading(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
    def run(self):

        getUrl(main())

def getUrl(page):
    i=1
    for nextpage in page:
        url = "http://book.zongheng.com/chapter/685640/{}.html".format(nextpage)
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.108 Safari/537.36'
        }
        response = requests.get(url,headers = headers)

        soup = BeautifulSoup(response.text,'html.parser')
        div = soup.findAll("div",class_ = "content")
        title = soup.findAll("div",class_ = "title_txtbox")
        #最终的标题
        souptitle = BeautifulSoup(str(title),'html.parser').text.strip("[]")
        #最终要写入文件的小说内容
        souptext = BeautifulSoup(str(div),'html.parser').text.strip("[]").replace("。","。\n")

        f = open("C:/f.txt","a")
        f.write(str(souptitle)+'\r')
        f.write(str(souptext)+'\r')
        f.close()
        #打印进度条
        sys.stdout.write("\r已经完成:{}%".format(i/len(page)*100))
        sys.stdout.flush()
        time.sleep(0.1)
        i = i+1

def main():
    a = ['38883752']
    for i in range(90):
        url = "http://book.zongheng.com/chapter/685640/{}.html".format(a[i])
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.108 Safari/537.36'
        }
        response = requests.get(url, headers=headers)
        soup = BeautifulSoup(response.text, 'html.parser')
        # 小说内容在div标签里
        nextpage = soup.body['nextchapterid']
        a.append(nextpage)
    return a

if __name__ == '__main__':
    strattime = time.time()
    thread1 = myThreading()
    thread1.start()
    thread1.join()
    print("")
    print("爬取完成")
    endtime = time.time()
    print("耗时:{}s".format(endtime - strattime))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/141324
推荐阅读
相关标签
  

闽ICP备14008679号