scrapy爬虫入门--爬取《糗事百科》内容(上):基础知识篇

爬取《糗事百科》-基础知识篇

一、scrapy简介

1、scrapy python的爬虫框架,非常出名,我们此处学用法,实现功能即可。有兴趣可以下载源码、理解,底层使用了多进程、多线程、队列等技术。


2、安装:pip installscrapy

注意如果出错:

building 'twisted.test.raiser' extension

error: Microsoft Visual C++ 14.0 is required. Get it with"Microsoft Visual C++ Build Tools": http://landinghub.visualstudio.com/visual-cpp-build-tools

解决方案:

    http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted

    下载twisted对应版本的whl文件(如我的Twisted-17.5.0-cp36-cp36m-win_amd64.whl),cp后面是python版本,amd64代表64位,运行命令:

    pip install C:\Users\Downloads\Twisted-17.5.0-cp36-cp36m-win_amd64.whl

3、框架的介绍:

由5部分组成

①  引擎

②  下载器(负责下载)、

③  spiders(爬虫文件)、

④  调度器(调度的、爬虫、给你一个url、爬完这个需要再去提取指定的url接着爬、调度器统一分发、生成一个请求对象,看让谁发送这个请求对象)

⑤  管道(pipeline)

我们的代码写到spider与管道中,spider里面实现内容解析、链接提取(比如爬取内容、不只爬取第一页内容,每页链接不一样);管道:决定数据是保存到mysql、文件、还是mongodb中。


4、scrapy工作原理:

见图片:

     先给个起始url,在spiders代码里放着,引擎会将起始url要过来,不做实际的工作,扔给调度器,调度器有个队列,负责调度,如果需要下载,出队给引擎,引擎不负责下载,扔给下载器,从互联网把数据下载下来,会将数据再扔给引擎,引擎将数据给spiders,spiders里面有解析内容的代码,解析时候会有你想要的数据,存放到一个字典中,(不仅有数据。还会有其他的url)总之,解析完之后有两种结果,url与数据,如果是数据,扔给引擎,引擎扔给管道,管道处理数据,存到哪里?mysql?mongodb?如果是url,就会给调度器,再重复上述的步骤。

    注意:

        爬虫核心:都在spiders里面;

        其他的 扔出去系统都会给处理的;

        管道里面也是需要自己写的;

        调度器里面也不需要自行编写。出队是系统决定的;

5、scrpy简单使用

(1)创建项目:

在当前文件夹 打开超级终端 

scrapy startproject firstblood

(scrapy路径、还有包都在此路径放着,你可以开启指令开始爬虫  cd进来,然后看下文)

*认识目录结构:(*为你需要打交道的文件)

firstblood

    firstblood(真正的项目文件)

        __pycache__(缓存文件)

        spiders(爬虫文件存放的位置)

            __pycache__

            __init__.py

            lala.py(爬虫文件、涉及文件的解析*)

        __int__.py(包的标志)

        items.py(定义数据结构的的地方*)

        middlewares.py(中间件)

        pipelines.py(管道文件*)

        settings.py(配置文件*)

    scrapy.cfg(不用管)

(2)生成爬虫文件

cd firstblood
scrapy genspider qiubaiwww.qiushibaike.com

qiubai:(爬虫的名字)

www.qiushibaike.com:(爬取的域名)

会生成一个qiubai.py文件:

# -*- coding: utf-8 -*-
import scrapy
class QiubaiSpider(scrapy.Spider):
    # 爬虫的名字
    name = 'qiubai'
    # 允许的域名, 是一个列表,里面可以放多个,一般都做限制
    allowed_domains = ['www.qiushibaike.com', 'www.baidu.com']
    # 起始url,是一个列表
    start_urls = ['https://www.qiushibaike.com/']
    # 解析函数,重写这个方法,发送请求之后,响应来了就会调用这个方法,函数有一个参数response就是响应内容,该函数对返回值有一个要求,必须返回可迭代对象
    def parse(self, response):
        pass

class QiubaiSpider()

  1爬虫的名字

  2允许的域名(多了一个限制,只爬取此域名下,不限制的话就是全爬取。如果域名比较多,此是一个列表,加逗号,往后接着写域名)

  3起始url(从哪儿开始爬取)

  4 def parse

(解析函数,写解析的代码,发送的请求,响应过来之后,就在这里解析,重写这个方法,方法名不能改变,在这个方法中,响应就是传个参数,response(就是响应内容),会自动调用,不用再手动写,该函数对返回值有一个要求,就是返回可迭代对象)

*认识response对象

    程序是如何跑起来的:

    指令模式:

cd firstblood
firstblood
cd spiders
scrpycrawl qiubai

    运行之后、有三处错误:

    1.win32,注意版本

    2.取消遵从robots协议  settings.py 在第22行

    3.U-A头部信息改一下,粘个headers在后面。在第19行

    print(response.text)字符串类型

    print(response.body)打印的字节类型

    xpath():scrapy内部已经集成了xpath,直接使用即可,但是与原生的稍微有不同,后续会展示。


(3)执行输出指定格式     

scrapycrawl qiubai -o qiubai.json
scrapycrawl qiubai -o qiubai.xml
scrapycrawl qiubai -o qiubai.csv

            【注】你输出为csv的时候,中间估计有空行,自己百度一下解决掉即可

二、scrapy shell

1、scrapy shell是什么?

         是一个调试工具,常用来调试xpath对不对。

2、安装依赖:pip installipython

         更加智能的交互环境可以通过tab提示内容

         终端下任意位置,输入如下指令:

         scrapyshell 域名

3、属性

response.url 请求的url

response.body字节类型

response.text

response.status响应状态码

response.headers响应头

方法:xpath()提取出来的都是selector对象,需要进行extract()一下,然后再提取出来字符串

css():根据选择器进行获取指定的内容

 示例:

ret=response.css('#content-left>div?.authorimg::attr(src)')

ret=response.css('#content-left'>div>.authorh2::text')

ret[0].extract()

selector对象

    是scrapy自己封装的一个对象,不论你上面通过xpath还是css,获取到的都是这个对象

xpath()

css()

extract():将对象直接转化为字符串

extract_first():功能就等同于

         extract_first()==[0].extract()=extract()[0]

         如果xpath或者css写错了,返回一个空列表,通过后两种方式就会报错,但是通过extract_first()获取,就会获取none

item对象

         爬取数据的时候,第一步就是要定义数据结构,在item.py中定义,通过这个类创建的对象十分特殊,类似字典,字典怎么用,它就怎么用,这个对象可以快速地转换为字典

         回到ipthon输入:

         classPerson(scrapy.Item)(继承这个类)

                   name=scray.Field()

                   age=scray.Field()

         p=Person()(创建一个对象)

         p['name']='goudan'(赋值)

         p['age']=20

         p['name']打印

         p['age']

         type(p)

         d=dict(p)(转化为字典)


三、yield item和请求

1、yield是什么意思?

  deftest():
                   lt=[]
                   forx in range(1,11):
                            lt.append(x)
                   returnlt

如果写100个,1000个,一下生成1000个,写到列表中,都会显示出来,这样资源浪费,所以就引入了生成器。生成器,不是保存的数据,而是保存一个算法,用到的时候,直接调用,再给你生成。

def demo():
         forx in range(1,11):
                   yieldx
a=demo()
print(a)

此时demo就不再是个函数 a=demo() print(a)就是一个生成器

print(next(a))取出第一个数据
print(next(a))
print(next(a))
print(next(a))
print(next(a))

....

print(next(a))到第11个再取就会报错。

也可以遍历:

 for x in a:
                   print(x)
         defdemo():
                  for x in range(1,11):
                            yield x
                           print'嘻嘻嘻'
                  yield '哈哈哈'

         如果是print(next(a)),则只会打印一个1,嘻嘻嘻不会打印,只有打印下一个的时候,嘻嘻嘻才会打印

         函数中可以出现yield,证明这个函数是生成器,可以有多个yield


....

print(next(a))到第11个再取就会报错。

猜你喜欢

转载自blog.csdn.net/qq_29784441/article/details/80598642
今日推荐