首页 > 其他 > 详细

一个简单的爬虫实例---爬取百度贴吧小说

时间:2020-03-22 10:21:40      阅读:89      评论:0      收藏:0      [点我收藏+]

??最近在学习爬虫来爬取网站内容,本篇就是使用Python的requests库来爬取百度贴吧中小说吧里的一篇小说《黑道编年史》,并将其保存到本地文件中。百度贴吧的内容都是以“楼层发言”的形式呈现的,其中,只有楼主的发言的内容才是有用的小说内容,其余的都是无用的废话,好在百度提供了“只看楼主”的选项,可以只呈现楼主发言。我们很自安然想到使用requests库爬取网页内容,然后把楼主的发言保存到本地。

??开整!

??我们先观察网页内容,搜索框中“https://tieba.baidu.com/p/4961759818?see_lz=1&pn=1”,#see_lz=1#意思就是‘只看楼主’,然后,“pn=1”就是page_number为第一页,由此类推,第二页即为pn=2,这里我们很容易想到构建一个列表来存储每一页的url(本案例只有两页,可以手输,但是涉及到很多页的时候手输就不现实了),那么一共有多少页面呢,从下面的截图中可以看到显示总页数的位置以及相应的html中的标签,由此,每一页的url我们已经获取到。


技术分享图片


??然后就每一页的楼主的发言信息。检查元素楼主每层的信息,可以发现,楼主的内容都储存在一个<div>标签里面,属性为"d_post_content j_d_post_content ",根据这些信息我们使用“美丽汤”库很容易就可以获取到楼主的发言信息。但是这里有一个问题:<div>标签里面不只有正文部分,还有一些图片信息,并且图片的内容的数量是不一定的,在这里我网上搜了一个很简单很方便的一个小方法,[s.extract() for s in soup(‘img‘)]这一小段代码可以实现删除某个标签内的特定子标签。


技术分享图片


??然后剩下的就是往本地文件里写入的一些代码了,网上找的。下面就是我最终的代码,比较粗糙,诸位看官请赐教:

# -*- coding:utf-8 -*-


import requests
from bs4 import BeautifulSoup
import random
import sys

class get_novel_tieba(object):

    #定义类本身,包括小说的网址,每页网址,requests库中的header
    def __init__(self):
        self.url = "https://tieba.baidu.com/p/4961759818?see_lz=1"
        self.url_page = []
        self.headers = [{'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36'},
           {'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50'},
           {'User-Agent':'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)'},
           {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1'},
           {'User-Agent': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; 360SE)'}]
        self.title = ""
        self.content = []
        
    #定义函数,根据小说网址爬取每一页的的url
    def get_pageurl(self):
        req = requests.get(url=self.url, headers=self.headers[random.randint(0,4)])
        soup = BeautifulSoup(req.text)
        
        #文章题目
        title = soup.find("h3")
        self.title = title.text
        
        #每页的url
        toalpage = soup.find("span", class_="red", style = '')
        total_page_number= int(str(toalpage.text))
        for i in range(total_page_number):
            #设置只看楼主,检查元素可以看到每页的url为原网址+”see_lz=1&pn=”+页码
            self.url_page.append("https://tieba.baidu.com/p/4961759818?see_lz=1&pn="+str(i+1)) 

    #定义函数,根据每个页面的url爬取每页内容
    def get_content(self, url):
        req = requests.get(url=url, headers=self.headers[random.randint(0,4)])
        soup = BeautifulSoup(req.text)
        #除掉图片标签项
        [s.extract() for s in soup('img')]
        text = soup.find_all('div',class_='d_post_content j_d_post_content ')
        #得到的结果是当前页中每层楼中楼主的消息,然后遍历
        for i in range(len(text)):
            #每一层楼中也是每一段的列表,然后Tag类型转换为字符串
            for sentence in text[i]:
                sentence = str(sentence).replace('<br/>', '') #标签标识
                self.content.append(sentence)
                    
    #定义写进文件函数
    def writer(self, path):
        with open(path,"w",encoding ='utf-8') as f:
            f.writelines("%s\n" % ss for ss in self.content)
        
#主函数
if __name__ == "__main__":
    gn = get_novel_tieba()
    gn.get_pageurl() # 获取文章题目,及每页url
    print("开始下载。。。")
    for i in range(len(gn.url_page)):
        gn.get_content(gn.url_page[i]) # 获取文章内容 
        gn.writer("%s.txt" % gn.title) 
        sys.stdout.write("已下载%d页,共%d页。\n" % (i+1, len(gn.url_page)))
        sys.stdout.flush()
    print("下载完成。")

看看结果,小说都被完整的爬取下来了,当然不是很美观,空格太多,看着不是很舒服,另外段前再有缩进就更好了,这些,代码应该都是 能实现的:



技术分享图片



技术分享图片

后记

为了使这个段代码更有适用性,我想了下应该还是好几个可以提升的地方的:

  • 在选取楼主发言的时候,我们直接在网页上设置了“只看楼主”,但是如果没有这个选项的话我们还是可以通标签来筛选的。看下面截图,有一个属性为d_author的div标签储存作者信息,而楼主的发言有一个属性为”louzhubiaoshi“的标签,普通有课则没有,可以根据这个来筛选。但是它跟正文并不是一个父类标签,也就是说要找正文的父类标签的兄弟标签的子类标签有楼主标识的部分,这个我还没又找到方法。



技术分享图片

  • 在本篇中,楼主并没有灌水,但是在其他的小说吧中,相当一部分楼主为了博关注,灌了水,如何准确的筛选灌水和正文部分,也是一个难点。我想了一个可能不太十分准确的方法,根据字数,正文一般比较多,而灌水往往字数比较少。(当然也有例外)

  • 代码优化空间很大,需要学习的地方很多。我原本以为爬虫很简单,随便看几个案例就学会了,现在看来这远远不够,还要系统的学习下,requests库,BeautifulSoup库,urllib库内容还是很丰富的。

我还找到另外一个博友爬取小说的一个教程《Python实战项目网络爬虫 之 爬取小说吧小说正文》,不过他没有用BeautifulSoup库,用的正则表达式,可以相互借鉴下。

一个简单的爬虫实例---爬取百度贴吧小说

原文:https://www.cnblogs.com/shuai3290/p/12543704.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!