scrapy框架–基础结构加爬取异步加载数据的网址项目完整实例

28 篇文章 0 订阅

scrapy框架–基础加实例

  1. 为了提取网站数据,提取结构型数据而编写的应用框架,使用twisted高效异步网络框架来处理网络通信。
  2. Twisted 是用python实现的 基于事件驱动的网络引擎框架
    诞生于2000年初,网络游戏开发者发现无论用什么语言都有 可兼容 扩展性 及 跨平台 的网络库,支持常见的传输和应用层协议,兼容这些协议Ssl /tls、tcp udp http imap……
  3. 和Python一样 具有内置电池,所支持的协议都带有客户端和服务器端实现(client-sever)

一、结构

1.结构组成

在这里插入图片描述
1.engine(引擎):负责控制数据流在系统中所有组件中的流动,
触发其他几个中间件,相当于整个爬虫调度中心。
2.scheduler(调度器):接收引擎发来的requests请求,并加入队列,初始爬取url和网页中的待爬取url放入调度器等待被爬取,它会自动去重。
3.downloader(下载器):负责接受调度器的url,向服务器发送请求得到响应后将下载的网页内容提供给引擎 和spider(爬虫)。
4spider(爬虫) :分析response详细解析。
5.管道 :项负责数据的清洗、验证、过滤、去重和存储等后期处理,可同时连接十多个数据库,处理爬虫爬取出的item(封装过后的数据)。
下载中间件:引擎和下载器中间 l类似钩子函数 ,在特定情况下触发中间件,不能随意定义中间件,可以修改
爬虫中间件:引擎和下爬虫中间

2.爬取过程

Scrapy引擎发送请求,调度器把初始URL交给下载器,下载器向服务器发送服务请求,得到响应后将下载的网页内容交与蜘蛛来处理,蜘蛛会对网页进行详细的解析。蜘蛛分析的结果有两种:一种是得到新的URL,之后再次请求调度器,开始进行新一轮的爬取,另一种是得到所需的数据,之后会转交给项目管道继续处理。最后由Pipeline输出到文件中,或者存入数据库等。

二、创建项目

1.下载依赖

pip install wheel 二进制安装包
pip install scrapy

2.基本命令

scrapy startproject    项目名字  (创建项目) 
cd 项目名字      (进入项目)
scrapy genspider 爬虫名 网址 (创建爬虫)
list 查看多少爬虫
进入指定爬虫进行爬虫
Cd spider路径 Vim 爬虫文件
scrapy crawl 爬虫名字 (分布式多线程) 如加名字:通用、 聚焦协程行爬虫

3.基本配置更改

1)关闭遵循机器人”君子协定“

# Obey robots.txt rules
ROBOTSTXT_OBEY = False

2)配置随机请求头

修改下载中间件类:

import random
import time
from time import sleep
from scrapy.http import HtmlResponse
'''
这个类主要用于产生随机UserAgent
'''
#创建一个随机请求头
class RandomUserAgent(object):
    #实例化一个USER_AGENTS
    def __init__(self,agents):
        self.agents = agents
    @classmethod
    def from_crawler(cls,crawler):
        return cls(crawler.settings.getlist('USER_AGENTS'))
    #添加随机请求头
    def process_request(self,request,spider):
        request.headers['User-Agent'] = random.choice(self.agents)

setting.py配置文件中定义多个请求头,并修改中间件类名(改成自己刚刚定义的随机请求头类):

DOWNLOADER_MIDDLEWARES = {
   'boss.middlewares.RandomUserAgent': 543,
}
#定义多个请求头
USER_AGENTS = {
    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)","Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Acoo Browser; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506)","Mozilla/4.0 (compatible; MSIE 7.0; AOL 9.5; AOLBuild 4337.35; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)","Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)","Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)","Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)","Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30)","Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/523.15 (KHTML, like Gecko, Safari/419.3) Arora/0.3 (Change: 287 c9dfb30)","Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527+ (KHTML, like Gecko, Safari/419.3) Arora/0.6","Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070215 K-Ninja/2.1.1","Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/20080705 Firefox/3.0 Kapiko/3.0","Mozilla/5.0 (X11; Linux i686; U;) Gecko/20070322 Kazehakase/0.4.5","Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.8) Gecko Fedora/1.9.0.8-1.fc10 Kazehakase/0.5.6","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.20 (KHTML, like Gecko) Chrome/19.0.1036.7 Safari/535.20","Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; fr) Presto/2.9.168 Version/11.52","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.11 TaoBrowser/2.0 Safari/536.11","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.71 Safari/537.1 LBBROWSER","Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; LBBROWSER)","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E; LBBROWSER)","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.84 Safari/535.11 LBBROWSER","Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)","Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; QQBrowser/7.0.3698.400)","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E)","Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; SV1; QQDownload 732; .NET4.0C; .NET4.0E; 360SE)","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E)","Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)","Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1","Mozilla/5.0 (iPad; U; CPU OS 4_2_1 like Mac OS X; zh-cn) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5","Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0b13pre) Gecko/20110307 Firefox/4.0b13pre","Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:16.0) Gecko/20100101 Firefox/16.0","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11","Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36",
}

3)设置爬虫的间隔时间,并关掉COOKIES

DOWNLOAD_DELAY = 2
COOKIES_ENABLED = False

三、项目实例-爬取豆瓣电影排排行榜

1.网站截图

在这里插入图片描述
所需信息都在一个div中,这里只爬取排行名次(rank)为例

2.items

import scrapy
class BossItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    movie_name = scrapy.Field()  # 电影名

3.selenium前情提要

selenium 需要浏览器驱动支持
安装:
pip install selenium
简介:
selenium最初是一个自动化测试工具,而python爬虫中使用它主要是为了解决requests无法执行javaScript代码的问题。
(1)selenium可以驱动浏览器自动执行自定义好的逻辑代码,也就是可以通过代码完全模拟成人类使用浏览器自动访问目标站点并操作
(2)selenium可以完全模拟浏览器的操作,比如跳转、输入、点击、下拉等...进而拿到网页渲染之后的结果,可支持多种浏览器

版本对应表:https://blog.csdn.net/huilan_same/article/details/51896672:https://blog.csdn.net/weixin_45532870/article/details/108589098
        下载地址 https://chromedriver.storage.googleapis.com/index.html
        下载完毕放到对应的python的安装目录下的Scripts中
导入方式:
        from selenium import webdriver

创建谷歌浏览器对象:  
        path = 谷歌浏览器驱动文件路径         如果是绝对路径 前面加r(原因:转义 如果是\n的话python检测会认为是换行)
        browser = webdriver.Chrome(path)  
访问网址:
        browser.get(url)  打来某个页面
        browser.page_source 获取页面源码
        browser.quit() 关闭

4.下载中间件

因为需要滚动滑轮触发异步加载数据,所以引入selenium模拟浏览器对也页面进行滚动操作。在下载中间件中添加以下方法:

  '''
    这个方法主要用于模拟浏览器滚动屏幕获取异步数据
    '''
    def process_response(self, request, response, spider):
        # Called with the response returned from the downloader.

        # Must either;
        # - return a Response object
        # - or raise IgnoreRequest

        bro = spider.bro

        bro.get(url=request.url)
        sleep(3)
        # 获取页面初始高度
        js = "return action=document.body.scrollHeight"
        height = bro.execute_script(js)
        # print("js=js=js=js=js=js=js=js=",height) # 2480
        # 将滚动条调整至页面底部
        bro.execute_script('window.scrollTo(0, document.body.scrollHeight)')
        # bro.execute_script('window.scrollTo(0, 2000)')
        # 定义初始时间戳(秒)
        t1 = int(time.time())
        # 定义循环标识,用于终止while循环
        status = True
        # 重试次数
        num = 0

        while status:
            # 获取当前时间戳(秒)
            t2 = int(time.time())
            # 判断时间初始时间戳和当前时间戳相差是否大于30秒,小于30秒则下拉滚动条
            if t2 - t1 < 30:

                new_height = bro.execute_script(js)
                # print("js=js=js=", new_height)  # 2481
                if new_height <= height:
                    time.sleep(1)
                    bro.execute_script(
                        'window.scrollTo(0, document.body.scrollHeight)'
                    )
                    # 重置初始页面高度
                    height = new_height
                    # 重置初始时间戳,重新计时
                    t1 = int(time.time())
                else:
                    status = False
            elif num < 3:
                print("# 当超过30秒页面高度仍然没有更新时,进入重试逻辑,重试3次,每次等待30秒")
                time.sleep(3)
                num = num + 1
            else:
                # 超时并超过重试次数,程序结束跳出循环,并认为页面已经加载完毕!
                print("滚动条已经处于页面最下方!")
                status = False
                # 滚动条调整至页面顶部
                bro.execute_script('window.scrollTo(0, 0)')
                break
            sleep(5)

        return HtmlResponse(url=spider.bro.current_url, body=bro.page_source, encoding='utf8', request=request)

5.爬虫文件

import scrapy
from boss.items import BossItem
from selenium import webdriver
class B1Spider(scrapy.Spider):
    name = 'b1'
    start_urls = ['https://movie.douban.com/typerank?type_name=%E5%89%A7%E6%83%85&type=11&interval_id=100:90&action=']
    def __init__(self):
        # 初始化Chrome的对象
        self.bro = webdriver.Chrome(executable_path=r'C:\Users\shiji\anaconda3\Scripts\chromedriver.exe')

    def parse(self, response):
        # sel = Selector(response)
        # book_list = sel.css('#movie-list-item unplayable unwatched > ul > li')
        item = BossItem()
        name = response.xpath(
            '//*[@id="content"]/div/div[1]/div[6]/div/div/div/div[1]/span[1]/a/text()').extract()
        for i in name:
            item['movie_name'] = i
            print(i)
        # item 传给pipeline
            yield item
    def closed(self, spider):
        print('关闭浏览器对象!')
        self.bro.quit()

6.pipeline 添加MySQL

更改setting配置 打开管道

ITEM_PIPELINES = {
   'boss.pipelines.BossPipeline': 300,
}

pipeline.py

import pymysql as db
class BossPipeline(object):
    def __init__(self):
        self.con = db.connect(user="root", passwd="123456", host="localhost", db="spiderdbtushu", charset="utf8")
        self.cur = self.con.cursor()
        self.cur.execute('drop table if exists mn')
        self.cur.execute(
            "create table mn(id int auto_increment primary key,"
            "movie_name varchar(200))charset='utf8'")

    def process_item(self, item, spider):
        self.cur.execute(
            "insert into mn(id,movie_name) values(NULL,%s)",
            (item['movie_name']))
        self.con.commit()
        return item

查询数据库:
在这里插入图片描述
为节省时间这里我只selenium滚动了一页数据,要想多次滚动,自己想想,小改一下哦

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值