python爬虫-初步使用Scrapy分布式爬虫(爬取mcbbs整合包保存名称及主要mod),大爱MC

首先介绍一下scrapy。

Scrapy一个开源和协作的框架,是为了页面抓取所设计的,使用它可以快速、简单、可扩展(通过中间件)的方式从网站中提取所需的数据。

工作流程如下:

 Scrapy Engine是scrapy的核心,负责数据流的管理。Spiders(爬虫)发出Requests请求,请求经由Scrapy Engine传递给Scheduler(调度器),Scheduler通过Downloader Middlewares(下载器中间件)传递Requests给Downloader(下载器),Downloader根据Requests从网络上下载数据,并给出结果Responses(这是爬取内容的结果),随后Downloader通过Spider Middlewares(爬虫中间件)将Response交给Spiders分析,Spiders分析得到Items交给Item Pipeline(管道)。

这里的Spider和Item Pipeline根据用户需求自行编写。(中间件也可以自行编写)

具体返回值设计可以参照官方中文文档:http://scrapy-chs.readthedocs.io/zh_CN/0.24/intro/tutorial.html

图片来自官方参考文档。

本次测试为爬取mcbbs整合包模块的帖子列表,并且获取每个帖子的链接,访问该链接页面并且获得主要内容标签内的文本,以“标题  : 主要mod”存入txt文本文件。

创建项目,mcbbs。

conda activate spider :激活一个python虚拟环境叫做spider,且spider这个虚拟环境目录下已经安装了scrapy。如何创建虚拟解释器环境,并且安装scrapy参见我的博客 :https://blog.csdn.net/zhouchen1998/article/details/81382006

创建成功后在对应位置生成项目文件夹,用pycharm打开,文件结构如下:

其中PackSpider为自定义爬虫。

1.首先,设置settings.py。

BOT_NAME = 'mcbbs'

SPIDER_MODULES = ['mcbbs.spiders']
NEWSPIDER_MODULE = 'mcbbs.spiders'
ITEM_PIPELINES = {
    'mcbbs.pipelines.McbbsPipeline': 1,
}
STORE = 'D:\get.txt'

ROBOTSTXT_OBEY = False
DOWNLOAD_DELAY = 1

设置延时之类的,生成的文件里都有但是注释了,改过来就OK。

2.完成Item书写。

因为我要保存帖子名称和主要mod内容,名称获取页面元素就ok,但是主要mod则是通过获得元素的链接进入帖子获取主要内容,并且保存,所以item设计如下。

items.py


import scrapy


class McbbsItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    link_url = scrapy.Field()
    dir_name = scrapy.Field()
    dir_content = scrapy.Field()

3.写你的爬虫PackSpider.py(这里看清结构和继承)

自定义爬虫必须继承Spider

因为项目简单,不详细注释了。

import scrapy
from scrapy import Selector
from mcbbs.items import McbbsItem
'''
爬取mcbbs整合包区块的整合包贴名,并且通过xpath或者re(正则表达式)进入相关链接爬取所含主要mod

'''


class PackSpider(scrapy.Spider):
    name = 'mc_pack'

    def __init__(self):
        # 帖子域名
        self.server_link = 'http://www.mcbbs.net'
        self.allowed_domains = ['www.mcbbs.net']
        str1 = 'http://www.mcbbs.net/forum.php?mod=forumdisplay&fid=170&page='
        # 产生前十列的所有链接
        self.start_urls = [(str1 + str(item)) for item in range(2, 51)]

    def start_requests(self):
        for item in self.start_urls:
            yield scrapy.Request(url=item, callback=self.parse1)

    # 解析内容获得每个帖子的地址
    def parse1(self, response):
        hxs = Selector(response)
        items = []
        # 获取链接
        urls = hxs.xpath(r'//a[@onclick="atarget(this)"]/@href').extract()
        # 获取帖子名称
        dir_names = hxs.xpath(r'//a[@onclick="atarget(this)"]/text()').extract()
        for index in range(len(urls)):
            item = McbbsItem()
            item["link_url"] = self.server_link + "/"+ urls[index]
            item["dir_name"] = dir_names[index]
            items.append(item)
        # 根据每个帖子链接,发送Request请求,传递item
        for item in items:
            yield scrapy.Request(url=item["link_url"], meta={"item": item}, callback=self.parse2)

    def parse2(self, response):
        item = response.meta['item']
        hxs = Selector(response)
        context = hxs.xpath(r'//tbody/tr[last()-2]/td/text()').extract()
        item["dir_content"] = context
        yield item

4.完成pipelines.py,数据落地。

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

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html
from mcbbs import settings
from scrapy import Request
import requests
import os

class McbbsPipeline(object):
    def process_item(self, item, spider):

        with open(settings.STORE, 'a') as f:
            f.write(item['dir_name']+"    :     ")
            f.write(str(item['dir_content'])+"\n")
        return item

5.注意,如果你用的pycharm来项目编辑,那么必须给一个入口模块。同时scrapy是异步的爬取顺序不是输入顺序。

main.py

其中mc_pack就是spider里面定义的name。

from scrapy import cmdline
if __name__ == '__main__':
    cmdline.execute('scrapy crawl mc_pack'.split())

 运行结果:

猜你喜欢

转载自blog.csdn.net/zhouchen1998/article/details/81328858