百度贴吧通用爬虫

号外!号外!号外!

喜欢逛贴吧的朋友们,你们的福利来啦!经过本人的一顿操作,我写出了百度贴吧的通用爬虫,只需要输入你想爬取的贴吧名字就可以进行内容的爬取。

  • 喜欢校花吗?来咱们一起看一看校花吧的首页吧
    看看这忧郁的眼神,瞬间征服了多少宅男的心(手动滑稽) 百度贴吧的请求地址如下:
http://tieba.baidu.com/f?ie=utf-8&kw=校花&fr=search&red_tag=r2338324287
复制代码

得到要请求的url之后进行胡乱分析(肯定是认真的啦),正如我们所见到的,这个url还是有那么一点点长的。其实啊,里面有一些东西是在我们爬虫里面用不到的,你比如咱们把fr字段和red_tag字段删掉,再请求一哈,肯定也是成功的啦,这时候的请求地址会相对简洁,当然啦,ie字段和对应的内容也是可以删除的。只有kw对应的字段是我们需要的,而kw对应的字段正是我们贴吧的名字。删减后的url地址如下:

http://tieba.baidu.com/f?kw=校花
复制代码

到了这里你是不是觉得已经完事儿了呢?当然不是!像这么大的吧肯定不止只有一页内容,所以我们来到当前页的底部,清楚的看到有很多页,如下

那点击下一页看看咯,注意注意注意(敲黑板啦),注意看一下当前的url有没有变化。点击下一页之后的url地址:

http://tieba.baidu.com/f?kw=校花&ie=utf-8&pn=50
复制代码

多了个ie和pn字段,前面我们已经说过ie字段是可以删掉的,因此pn字段肯定是控制页码的字段。为了验证以及寻找规律,咱们继续点击下一页。并观察url的变化。

http://tieba.baidu.com/f?kw=校花&ie=utf-8&pn=100
复制代码

这时pn字段对应的值变成了100,经过反复点击之后,我发现每次pn的变化都是累加50 且首页的pn值为0,即我们请求的其实url应该是它:

http://tieba.baidu.com/f?kw=校花&pn=0
复制代码

好了,接下来就要分析页面了,咱们一步一步走通之后再写代码,进行调试。 首页,在检查模式下的network中找到我们响应的url,并保存headers里面的部分内容,这是为了咱们模拟请求的时候用的。具体如下图:

在response中寻找我们要找提取的数据,可以直接Ctrl+f在response里面搜索你看到帖子的标题
这就是帖子的标题,title对应的字段就是帖子的url地址,这下都找到了,很棒啦。,但是它是绿色的,为什么是绿色的啊?好好的为什么是绿色的啊?我们继续往上翻。果然不出我所料,注释了。莫非这就是百度贴吧的反爬手段?
查看网页源码之后发现我们所需要的内容是在code标签里面,接下来就是对它的请求与解析啦,直接上代码啦:

import requests
import json
import re


class TiebaSpider:
    def __init__(self, tieba_name):
        self.tieba_name = tieba_name
        self.start_url = "http://tieba.baidu.com/f?kw=" + tieba_name + "&pn=0"
        self.part_url = "http://tieba.baidu.com"
        self.headers = {
            "accept-encoding": "gzip, deflate",
            "accept-language": "zh-CN,zh;q=0.9",
            "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
            "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36"
        }

    def save_content_list(self, content_list):
        file_path = self.tieba_name + ".txt"
        with open(file_path, "a", encoding="utf-8") as f:
            # 遍历列表 分别写入
            for content in content_list:
                f.write(json.dumps(content, ensure_ascii=False, indent=2))
                f.write("\n")

    def parse_url(self, url):
        print(url)
        toggle = False
        curr_pagen = int(re.findall(r'&pn=(\d+)', url)[0])
        # 构造下一页url
        next_pagen = re.sub(r'&pn=(\d+)', r'&pn={}'.format(curr_pagen + 50), url)
        # 发送请求,获取响应
        response = requests.get(url, headers=self.headers, timeout=20)
        html_str = response.content.decode()
        # 使用正则提取全部img_url
        img_url_list = re.findall('bpic *= *"([^"]+)', html_str)
        # 提取"/p/6086393083" title="感觉自己萌萌哒" target="_blank" class="j_th_tit ">感觉自己萌萌哒
        title_list = re.findall('<a rel=\"noreferrer\" href=(.*?)</a>', html_str)
        content_list = []
        for title in title_list:
            toggle = True
            item = {}
            # 提取title内容
            title_temp = re.search(">(.*?)<", title + "<")
            item["title"] = list(title_temp.groups())[0]
            # 提取href内容
            href_temp = re.search("\"(.*?)\"", title)
            item["href"] = self.part_url + list(href_temp.groups())[0]  # 我们得到的img_url是这样的/p/6052917512,所以此处要拼接
            print(item["href"])
            # 提取img_url内容
            item["img_list"] = [img_url for img_url in img_url_list][0]
            # 把得到的数据添加到一个列表里面
            content_list.append(item)

        self.save_content_list(content_list)
        return toggle, next_pagen

    def run(self):
        toggle, next_url = self.parse_url(self.start_url)
        while toggle:
            toggle, next_url = self.parse_url(next_url)


if __name__ == '__main__':
    tieba_spider = TiebaSpider("校花")
    tieba_spider.run()

复制代码

运行之后咱们看一下结果

很快就爬取了100条数据,这里我手动暂停了,有兴趣的同志们可以让它一直运行下去,咱们再来看看爬取保存的结果
我们要的数据都在这里保存啦,可以说基本成功啦。
做自己的舔狗,嘻嘻嘻。这段代码我总觉得不够完美,所有请路过的大佬斧正,共同进步! 另外非常感谢一位不愿透露姓名的大佬指点,非常感谢!

溜溜球啦~

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值