关闭

Scrapy 爬取百度贴吧指定帖子的发帖人和回帖人

标签: 爬虫pythonscrapy
2573人阅读 评论(0) 收藏 举报
分类:


这里写图片描述
打开微信扫一扫,关注微信公众号【数据与算法联盟】

转载请注明出处:http://blog.csdn.net/gamer_gyt
博主微博:http://weibo.com/234654758
Github:https://github.com/thinkgamer

前言

该篇文章将是Scrapy爬虫系列的开篇,随后会不定时更新该框架方面的内容和知识,在scrapy之前写爬虫主要用的BeautifulSoup, request 和urllib,但随着使用程度的加深,慢慢意识到功能和效率都是不够的,那么便重新接触了Scrapy框架,并尝试着写出一些有趣的东西。

什么是Scrapy

它是一个应用程序框架,用来抓取并提取网站中的结构化数据,在数据挖掘,信息处理等方面十分有用。

安装

pip install Scrapy

它是一个python包,依赖于以下几个python包

  • lxml : XML和HTML解析
  • parsel :基于lxml的HTML/XML解析器
  • w3lib :处理网页编码和URL解析器
  • twisted :一个异步网络框架
  • cryptography and pyOpenSSL :处理各种网络级安全需求

创建一个简单的项目

scrapy startproject tiebaSpider

目录结构为

tiebaSpider/
    scrapy.cfg            # 配置文件

    tiebaSpider/             # py 模块
        __init__.py

        items.py          # 定义一些数据模型文件

        pipelines.py      # 管道,用来进行数据的保存

        settings.py       # 关于项目的一些配置

        spiders/          # 该目录下编写自己的代码逻辑
            __init__.py

在soiders/下新建一个tibe.py文件,内容为:

# coding: utf-8

import scrapy

class TiebaSpider(scrapy.Spider):
    name = "tiebaSpider"

    def start_requests(self):
        urls = [
            'https://tieba.baidu.com/f?kw=%E6%88%92%E8%B5%8C&ie=utf-8&pn=0'
        ]

        for url in urls:
            yield scrapy.Request(url=url, callback=self.parse)

    def parse(self,response):
        page = response.url.split("pn=")[1]
        filename = "tieba-%s.html" % page
        with open(filename, 'wb') as f:
            f.write(response.body)
        self.log('Saved file %s' % filename)
  • name: 爬虫名字
  • start_requests: 返回一个可迭代的请求地址
  • parse: 解析网页的函数
  • yield:python 生成器

运行爬虫:

scrapy crawl tiebaSpider

这里我们也可以这样写

# coding: utf-8

import scrapy

class TiebaSpider(scrapy.Spider):

    name = "tiebaSpider"

    start_urls = [
        'https://tieba.baidu.com/f?kw=%E6%88%92%E8%B5%8C&ie=utf-8&pn=0',
        ]
    def parse(self,response):
        page = response.url.split("pn=")[1]
        filename = "tieba-%s.html" % page
        with open(filename, 'wb') as f:
            f.write(response.body)
        self.log('Saved file %s' % filename)

因为parse是scrapy的默认回调函数,当然如果你要写好几自己定义的函数的话,就必须要指定自己的回调函数。

爬取贴吧用户

背景

爬取贴吧的尽可能多的用户名,作为推广使用(暂时使用以下的方法来获取用户名,后续会更新一种新的方法:对于给定的贴吧名,爬取其前三页所有帖子的发帖人和回帖人,这里只保存用户名)

分析

这里的实现思路是search 出来指定的贴吧,然后获取所有贴吧前三页的帖子 href,然后保存到文件中,再启用另外一个爬虫逐个帖子去爬取解析用户名

代码结构

tieba
  data
  tieba
    spiders
      __init__.py
      tieba1.py     # 获取所有的帖子的链接
      tieba2.py     # 获取发帖人和回帖人的用户名
    __init__.py
    items.py
    middlewares.py
    pipelines.py
    settings.py
  name.txt           #存放贴吧名
  scrapy.cfg

代码实现

tieba1.py

# coding: utf-8

import scrapy
import urllib
import time


class TiebaSpider(scrapy.Spider):

    name = 'tieba'

    def __init__(self):
        self.urls = []

        # 加载贴吧名
        fr = open("name.txt", "r")

        for one in fr.readlines():
            for i in range(0, 3):
                self.urls.append('https://tieba.baidu.com/f?kw=' +
                                 urllib.quote(one.strip()) + '&ie=utf-8&pn=' + str(i * 50))
        fr.close()

    def start_requests(self):
        urls = self.urls

        for url in urls:
            yield scrapy.Request(url=url, callback=self.parse)

    def parse(self, response):
        sel = scrapy.Selector(response)
        ahref_list = sel.xpath(
            '//a[re:test(@class, "j_th_tit ")]//@href').extract()

        fw = open("data/%s_all_href.txt" % time.strftime('%Y%m%d'), "a")
        for ahref in ahref_list:
            href = "https://tieba.baidu.com" + ahref
            fw.write(href + "\n")
        fw.close()

tieba2.py

# coding: utf-8

import scrapy
import time
from scrapy.http.request import Request
from scrapy.http import HtmlResponse

class TiebaSpider2(scrapy.Spider):

    name = 'tieba2'

    def __init__(self):
        self.urls = []

        # 加载贴吧名
        fr = open("data/%s_all_href.txt" % time.strftime('%Y%m%d'), "r")

        for one in fr.readlines():
            self.urls.append(one.strip())
        fr.close()

    def start_requests(self):
        urls = self.urls

        for one in urls:
            yield scrapy.Request(url=one, callback=self.parse)

    def parse_uname(self, response):
        # response = HtmlResponse(url=page_url.url)
        sel = scrapy.Selector(response)
        name_list = sel.xpath('//li[re:test(@class, "d_name")]//a/text()').extract()
        # print respons        
        fw = open("data/%s_all_name.txt" % time.strftime('%Y%m%d'), "a")
        for name in list(set(name_list)):
            fw.write(name.encode("utf-8"))
            fw.write("\n")
        fw.close()

    def parse(self, response):
        sel = scrapy.Selector(response)

        # 可能有些帖子被删除
        try:
            # 得到每个帖子有多少页
            num = int(sel.xpath('//span[re:test(@class,"red")]//text()').extract()[1])   
            # 遍历每页获得用户名
            for page_num in range(1, num + 1):
                one_url = response.url + "?pn=" + str(page_num)

                yield Request(url=one_url, callback=self.parse_uname) 
        except Exception as e:
            pass

代码的github地址为:点击查看

总结

相比BeautifulSoup ,urllib,request来讲,Scrapy更加的快捷,高效和灵活,而且使用lxml,parsel 来进行网页内容的解析比BS也更快

2
1
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

Scrapy 爬取百度贴吧指定帖子的发帖人和回帖人

该篇文章将是Scrapy爬虫系列的开篇,随后会不定时更新该框架方面的内容和知识,在scrapy之前写爬虫主要用的BeautifulSoup, request 和urllib,但随着使用程度的加深,慢慢...
  • Gamer_gyt
  • Gamer_gyt
  • 2017-07-13 09:26
  • 2573

《python爬虫实战》:爬取贴吧上的帖子

《python爬虫实战》:爬取贴吧上的帖子经过前面两篇例子的练习,自己也对爬虫有了一定的经验。 由于目前还没有利用BeautifulSoup库,因此关于爬虫的难点还是正则表达式的书写。但是,当写几个...
  • u010412719
  • u010412719
  • 2015-12-06 22:18
  • 8818

Python 爬虫获取某贴吧所有成员用户名

最近想用Python爬虫搞搞百度贴吧的操作,所以我得把原来申请的小号找出来用。有一个小号我忘了具体ID,只记得其中几个字母以及某个加入的贴吧。所以今天就用爬虫来获取C语言贴吧的所有成员。计划很简单,爬...
  • u011054333
  • u011054333
  • 2017-04-05 00:44
  • 1185

python3 多页爬虫爬取百度贴吧帖子所有图片

逛博客,发现了python。说是人工智能开发的主要语言,所以就来了兴趣,打算抽空看看。网上找了教程觉得语法上,相较于.net和java反倒更简单点。基本语法看完,总要弄点东西吧
  • caopeihuaaini
  • caopeihuaaini
  • 2017-07-18 09:08
  • 675

Python爬取百度贴吧帖子

首先贴自己遇到的问题: 'gbk' codec can't encode character '\u20af' in position 566: illegal multibyte sequence...
  • Waterkong
  • Waterkong
  • 2017-05-29 10:14
  • 482

Python爬虫实战二之爬取百度贴吧帖子

原文:http://cuiqingcai.com/993.html 本篇目标 1.对百度贴吧的任意帖子进行抓取 2.指定是否只抓取楼主发帖内容 3.将抓取到的内容分析并保存到文件 ...
  • jingza
  • jingza
  • 2016-10-09 15:03
  • 331

python爬虫(13)爬取百度贴吧帖子

爬取百度贴吧帖子 一开始只是在网上看到别人写的爬取帖子的文章,然后自己就忍不住手痒自己锻炼一下, 然后照着别人的写完,发现不太过瘾, 毕竟只是获取单个帖子的内容,感觉内容稍显单薄,然后自己重新做了修...
  • qiqiyingse
  • qiqiyingse
  • 2017-04-14 20:15
  • 6094

python爬虫小项目: 爬取百度贴吧帖子

本文同样是基于静觅系列的python3.x版,具体步骤请前往静觅系列学习 关于encode()与decode()的问题:可以参照xanderzhang 及921800467的专栏 可完成静觅系列相同功...
  • funj_
  • funj_
  • 2016-11-04 20:24
  • 1615

爬取百度贴吧用户的帖子

在基于Python爬虫实战二之爬取百度贴吧帖子的项目–崔庆才(http://cuiqingcai.com/993.html),该项目最终爬取一个贴子的所有楼层或者只看楼主。 想到自己可以爬取一个用户...
  • sinat_36802840
  • sinat_36802840
  • 2016-12-19 19:16
  • 227

Python爬虫试水————爬取丽水学院百度贴吧帖子信息&分析

这周试着学了下Python 于是准备做个小爬虫练练手 —————————————————————————————— 以下是爬取结果的分析: 爬取目标,百度 丽水学院 贴吧 截止至 2017年2月19号...
  • xiaofeng187
  • xiaofeng187
  • 2017-02-19 21:27
  • 672
    Thinkgamer微博
    微信公众号【数据与算法联盟】

    扫码关注公众号,获取小编微信拉你进数据算法大佬群!
    个人资料
    • 访问:994160次
    • 积分:11213
    • 等级:
    • 排名:第1630名
    • 原创:221篇
    • 转载:22篇
    • 译文:2篇
    • 评论:331条
    个人简介
    姓名:Thinkgamer

    Github:https://github.com/thinkgamer

    主攻:云计算/python/数据分析

    程度:熟悉/熟悉/熟悉

    微信:gyt13342445911

    Email:thinkgamer@163.com

    工作状态:在职ing

    心灵鸡汤:只要努力,你就是下一个大牛...

    hadoop/spark/机器学习群:279807394(大神建的群,蹭个管理员)

    欢迎骚扰........
    博客专栏
    最新评论