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

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
云解析DNS,个人版 1个月
简介: 打开微信扫一扫,关注微信公众号【数据与算法联盟】 转载请注明出处:http://blog.csdn.net/gamer_gyt 博主微博:http://weibo.


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

转载请注明出处: 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月前
|
数据采集 Python
爬虫实战-Python爬取百度当天热搜内容
爬虫实战-Python爬取百度当天热搜内容
119 0
|
2月前
|
数据采集 中间件 Python
Scrapy爬虫:利用代理服务器爬取热门网站数据
Scrapy爬虫:利用代理服务器爬取热门网站数据
|
14天前
|
数据采集 存储 缓存
使用Scrapy进行网络爬取时的缓存策略与User-Agent管理
使用Scrapy进行网络爬取时的缓存策略与User-Agent管理
|
21天前
|
Web App开发 iOS开发 Python
经验大分享:scrapy框架爬取糗妹妹网站qiumeimei.com图片
经验大分享:scrapy框架爬取糗妹妹网站qiumeimei.com图片
10 0
|
2月前
|
数据采集 存储 JavaScript
Buzz库网络爬虫实例:快速爬取百度搜索实时热点
Buzz库网络爬虫实例:快速爬取百度搜索实时热点
|
10月前
|
Python
一个爬取百度图片的脚本
一个爬取百度图片的脚本
40 1
|
11月前
|
数据采集 Python
用python爬取百度上的特定图片
用python爬取百度上的特定图片
129 1
|
2月前
|
Web App开发 IDE 测试技术
实战练习:用airtest-selenium脚本爬取百度热搜标题
实战练习:用airtest-selenium脚本爬取百度热搜标题
|
2月前
|
数据采集 JavaScript 开发者
使用Scrapy有效爬取某书广告详细过程
使用Scrapy有效爬取某书广告详细过程
使用Scrapy有效爬取某书广告详细过程
|
11月前
|
XML 数据采集 JSON
scrapy_selenium爬取Ajax、JSON、XML网页:豆瓣电影
在网络爬虫的开发过程中,我们经常会遇到一些动态加载的网页,它们的数据不是直接嵌入在HTML中,而是通过Ajax、JSON、XML等方式异步获取的。这些网页对于传统的scrapy爬虫来说,是很难直接解析的。那么,我们该如何使用scrapy_selenium来爬取这些数据格式的网页呢?本文将为你介绍scrapy_selenium的基本原理和使用方法,并给出一个实际的案例。