鸟与虫(三)贴吧,我想粗去玩

  • 哈罗啊,又见面了,这几天考试+各种事情,耽误了点时间,不够我终于又做了个案例
  • 还是看着知乎大神的帖子Wakingup的帖子
  • 话不多说,上代码
'''
    根据知乎大神

    代码作者:高佳乐

'''
##先导入各种库
import re                                      ##re正则表达式
import requests                                ##获取url
from bs4 import BeautifulSoup                  ##bs4解析
import time                                    ##爬虫嘛,要有礼貌
import random                                  ##开始我想用随机数转换head来着,试了试没事
import os                                      ##弄文件及,一页一个文件夹
from lxml import etree                         ##xpath的库

##定义一个类,爬虫
class spider():
    ##初始化
    def __init__(self):                        ##初始化函数
        self.url = 'http://tieba.baidu.com'     ##使他的初始化函数是贴吧首页
        return
    ##获取贴吧的url
    def getUrl(self,url):                       ##获取url的函数(参数是一个url,网址)
        html = requests.get(url)                ##html是requests.get获取到的源码
        html_text = html.text                   ##html_text是上边获取到代码后然后书写进来
        return html_text                        ##这个函数返回html_text以便赋值

    ##获取帖子的标题
    def title(self,url):
        html = self.getUrl(url)                 ##html是用getUrl获取到的代码
        soup = BeautifulSoup(html,'lxml')       ##soup是用BeautiflSoup解析的结构树,用的是lxml
        title = soup.find(class_="core_title_txt")##然后获取class=“core_title_text”的节点
        #print('这个贴吧的标题是:',title.get_text())    ##这个已经注释了,解释也没用了
        return title.get_text()                     ##返回的是上边获到标题节点的内容


    ##获取帖子的总页数
    def pages(self,url):                        ##这个函数是获取总页数
        html = self.getUrl(url)                 ##html是用getUrl获取到的代码
        soup = etree.HTML(html)                 ##然后soup是用etree.HTML把上边获得的代码解析,以便使用xpath
        pages = soup.xpath('.//div[@id="thread_theme_5"]//li[@class="l_reply_num"]/span[last()]')##因为用正则有点麻烦我感觉,用bs4我也觉得有点烦,就用了xpath,xpath刚开始用,原谅我太菜
        for page in pages:                      ##上边的xpath是在此节点中不管那个位置的id=“thread_theme_5的div里不管在哪的class=“l_reply_num”的li的最后一个span
            break;                              ##因为获得的是列表,所以要遍历,因为我只获取一个值,所以我在这个循环里循环后直接结束
        return page.text                        ##因为上边返回的是一个那样的,所以返回值带上text返回文本



    ##获取楼主和内容
    def content(self,url):                      ##获取楼主的内容,参数是url
        html = self.getUrl(url)                 ##html是用getUrl获取到的代码
        ##我用的正则,有点麻烦,用在我这个帖子里好使,别的没准就报错了,推荐用xpath或者Bs4
        zhengze = re.compile('<li.*?_author_name.*?_blank.*?(.*?)</a>.*?d_post_content.*?save_face_bg_hidden.*?d_post_content j_d_post_content.*?>(.*?)</div>',re.S)
        contents = re.findall(zhengze,html)     ##上边是定义一个正则,这里就是使用在html筛选上边条件的全部节点,返回列表
        number = 1 ##计数器,这是个记住器,以便记住第几楼
        for i in contents:
            print('第%d个帖子\n楼主:%s\n内容:%s\n'%(number,i[0],i[1]))
            print()
            number+=1

    ##获取图片
    def img(self,url):                          ##获取图片的函数
        html = self.getUrl(url)                 ##html也是用getUrl获取的代码
        soup = BeautifulSoup(html,'lxml')       ##soup是用BS4解析的代码,用的lxml
        images = soup.select('img[class="BDE_Image"]')##然后用select查到符合‘class=“BDE_Image”’的img标签,返回列表
        number = 0                                 ##这是个计数器,
        imgs = []                               ##这里创建一个空列表以便吧图片地址存到这里,你会问上边不是有了吗,其实上边是有列表,但是上边的是节点的列表就是还设有别的属性,咱们只要scr属性的
        for i in images:                        ##这是一个计一页有多少图片的方法,当然这是最屌丝的方法
            number+=1                           ##读取一个节点,number+1
        if number > 0:                          ##计数下来,number>0的话
            print('厉害,厉害,这里有%s个图片,爬完就跑,刺激'%number)##输出这点话
        else:                                   ##反之就是<=0  就说这话
            print('这里没有图片,快跑')
        number = 1                              ##这里number在=1,以便计数
        for image in images:                    ##用image在images读取,也就是在上边爬到的图片节点中读取
            img = image.get('src')              ##这里get(src)就是,img只获得这个节点的src属性,就是纯url了
            print('正在爬取,第%d图片:'%number,img)##输出上边获取图片的url
            imgs.append(img)                    ##然后把上边的纯连接img追加到开始创建的那个空列表里,这不就会成为一个纯连接的列表了
            number+=1                           ##number+1 以便计数
        return imgs                             ##返回那个纯连接的列表


    ##创建文件夹,和图片
    def make(self,name):                        ##创建文件夹的函数
        dir = os.getcwd()+'\第'+str(name)+'文件夹'  ##先定义文件的名字,就是os.getcwd获取当前工作路径,+文件夹的名
        # 去除首位空格
        dir = dir.strip()
        # 去除尾部 \ 符号
        dir = dir.rstrip('\\')
        ##判断目录是否存在
        panduan = os.path.exists(dir)               ##exists判断目录是否存在,是=true,否=False
        if panduan:                                 ##如果有就已存在
            print(dir,'已存在')
        else:                                       ##反之,也就是假,没有
            os.makedirs(dir)                        ##就创建这个文件夹,当然我这的路径是绝对路径
            print(dir,'已创建成功')

        return dir                                  ##返回那个文件夹的路径,以便下边的切换路径


    ##保存图片
    def saveimage(self,url):                        ##保存图片了
        images = self.img(url)                      ##images是用img获取到的纯连接的那个列表
        num = 1                                     ##num=1计数器
        for img in images:                          ##用循环让img在那个返回的纯连接的列表里读取
            fil = str(num) + '.jpg'                 ##然后定义图片名字.jpg
            html = requests.get(img).content        ##因为直接一个地址是写不到图片里边去的,要写入二进制,所以要先获取那个图片的内容,然后.content转化成二进制
            f = open(fil,'wb')                      ##然后打开fil的文件可写可读,没有就是创建
            f.write(html)                           ##然后写入图片的二进制
            f.close()                               ##然后关闭,随手关闭是个好孩子
            num+=1                                  ##当然计数器要+1
            print('第%s保存成功'%fil)                ##提示图片保存成功更有逼格

    ##操控,一个贴吧的操控
    def all(self,number):                           ##这个函数就是把所有的方法封装到这里
        ##贴吧地址是self.url+帖子号
        url = self.url+'/p/'+str(number)            ##因为地址也是首页+帖子号,这个也是第一页
        ##获取标题
        title = self.title(url)                     ##有title方法获取标题
        print('这个帖子的标题是%s'%title)

        ##获取总页数
        page = int(self.pages(url))                 ##用pages获取帖子总页数,并转换成整数型,以便下边的+1

        ##根据总页数获取全部的页数,并获取图片
        num = 1                                     ##num这里就是计数,页数了
        print('第1页')                                ##这里是第一页
        ##获取内容
        self.content(url)                           ##第一页是不加pn的所以要单独分开来获取,url是上边弄得首页+帖子号,这里是获取内容和楼主
        self.img(url)                               ##这里是获取图片的详细资料
        dir = self.make(num)                        ##这里是创建文件夹,因为一页保存一个文件夹,所以这是第一个
        os.chdir(dir)                               ##上边创建好文件夹后,转换到文件夹下
        self.saveimage(url)                         ##然后保存,然后就跑
        num+=1                                      ##第一页保存了,当然是第二页了,后边的页数也不一样了,
        for i in range(num,page+1):                 ##之前获取到的总页数在这里,因为要获取全部,第一页之前已经获取了,这里既是从第2页开始到总页数+1后停止,为什么+1?因为for取首不娶尾
            url_2 = url + '?pn=' + str(i)           ##这里是给每页的url获取,因为第二页后每页都是首页+帖子号+?pn=页数了
            print('第%d页'%i)                         ##计数第几页
            time.sleep(1)                           ##爬虫要礼貌,礼貌,所以要sleep,1.。其实我打算想着0.1,但是为了世界和平所以要大点了,→_→
            self.content(url_2)                     ##获取第i页这内容
            self.img(url_2)                         ##获取第i页图片详情
            dir = self.make(i)                      ##然后创建第i个文件夹,根据i的数创建
            os.chdir(dir)                           ##然后切换到新创建的第i个文件夹里
            time.sleep(1)                           ##然后讲一下礼貌
            self.saveimage(url_2)                   ##然后保存第i页的图片
            time.sleep(1)                           ##再讲一下礼貌



img = spider()
img.all(int(input('输入帖子号')))

  • (这段是一个内心的小活动,可以省略看下边)
    学校换老师开始前端实例了┓( ´-` )┏,偷偷告诉你们我其实学的专业是ui设计,不会代码的ui不是一个好美工( ̄ー ̄),所以我决定好好学前端了,据说这样可以避免以后工作上和程序员的矛盾,嘛哈哈哈。当然爬虫我也要抓住,好不容易有这样的机会。

  • 这里,这次是把贴吧,旅游吧里的一个帖子爬图片和内容,足不出户,就可以看美景,还出去什么旅游,还不如在宿舍乖乖敲代码。emm对了我那个抓取楼主和内容的时候用的正则,可能我这好使别的就不好使了,没时间改xpath了(其实不也不知道能不能改),见谅。

  • 好了到了这就要再见了,砸门下次再见。坚持,加油,努力。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,050评论 4 370
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,538评论 1 306
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,673评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,622评论 0 218
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,047评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,974评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,129评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,893评论 0 209
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,654评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,828评论 2 254
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,297评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,619评论 3 262
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,326评论 3 243
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,176评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,975评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,118评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,909评论 2 278

推荐阅读更多精彩内容