Scrapy爬虫框架学习笔记

概念图

快速入门

在pycharm 安装scrapy

 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple scrapy

安装后创建项目

scrapy startscrapy game

创建后目录结构如图

项目创建后,创建spider爬虫

scrapy genspider xiao 4399.com

xiao是爬虫的名字,4399.com是爬取的范围,执行完毕后会创建一个xiao.py的spider

返回对象在parse解析,例如print(resopnse.txt)等,注意需要设置日志级别,否则会打印出很多不需要的信息

settings还可以配置,user-agent,协程的并发数量,robot协议等

然后传递数据到管道,在管道进行各种操作,持久化到数据库等

传递数据到管道用关键词yield

 

管道默认不开启,需要手动在settings.py中解除注释

管道可以有多个并存,且数值越小,优先级越高

运行scrapy代码,需要在terminal输入,xiao是spider名称

scrapy crawl xiao # xiao是spider名称
创建项目步骤总结

在python控制台想对scrapy crawl python的结果进行搜索,很麻烦,在run中搜索很方便,可以使用一下方式,将terminal的结果转到run显示

spider取数据,
class ShuangseqiuSpider(scrapy.Spider):
    name = "shuangseqiu"
    allowed_domains = ["500.com"]
    start_urls = ["https://datachart.500.com/ssq/history/outball.shtml"]

    def parse(self, response, *args, **kwargs):
        response.css('.class_t_tr1')
        for tr in response.css('.t_tr1'):
            qihao=tr.css('td::text').extract_first()

            date=tr.xpath('.//td[2]/text()').extract_first()

            red_balls=tr.xpath('.//td[@class="t_tdb1 t_cfont1"]/text()').extract()

            blue_ball= tr.xpath('.//td[@class="t_cfont4"]/text()').extract_first()

            cai=CaipiaoItem()
            cai['qihao']=qihao
            cai['date']=date
            cai['red_ball']=red_balls
            cai['blue_ball']=blue_ball

            yield cai
将结果封装成item,进行传递
class CaipiaoItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    qihao=scrapy.Field()
    red_ball=scrapy.Field()
    blue_ball=scrapy.Field()
    date=scrapy.Field()

到pipeline数据持久化

记得要return数据,不然后面其他管道接收不到,

多个pipeline之间通过在settings设置优先级,数值越小,优先级越高

csv
class CaipiaoPipeline:
    def open_spider(self, spider):
        self.f=open('./test.csv', 'a', encoding='utf-8')

    def close_spider(self, spider):
        if self.f:
            self.f.close()
    def process_item(self, cai, spider):
        print("csv---------")
        self.f.write(f'{cai["qihao"]},{cai["date"]},{"_".join(cai["red_ball"])},{cai["blue_ball"]}\n')
        return cai
mysql

导包

import pymsql

创建库

create database spider;

创建表

create table capiao(
    id int(11) primary key auto_increment,
    qihao varchar(100),
    date date,
    red_ball varchar(100),
    blue_ball varchar(100)
);

pipeline

class CaipiaoMySqlPipeline:
    def open_spider(self, spider):
        self.conn=pymysql.Connection(
            host=MYSQL['host'],
            port=MYSQL['port'],
            user=MYSQL['user'],
            passwd=MYSQL['passwd'],
            database=MYSQL['database'],
        )
    def close_spider(self, spider):
        if self.conn:
            self.conn.close()

    def process_item(self, cai, spider):

        try:
            #创建游标
            cursor=self.conn.cursor()
            sql="insert into capiao (qihao,date,red_ball,blue_ball) values (%s,%s,%s,%s)"
            cursor.execute(sql,(cai["qihao"],cai["date"],"_".join(cai["red_ball"]),cai["blue_ball"]))
            self.conn.commit()
        except:
            self.conn.rollback()
        finally:
            if cursor:
                cursor.close()

        print("msyql-------------")
        return cai

项目实战,扒一个风景图片网站

创建爬虫项目

scrapy startproject fengjingtu

创建spider

 scrapy genspider fengjingt tupianzj.com

到settings调整log级别

LOG_LEVEL = 'WARNING'

写爬虫业务逻辑

spider:

class FengjingtSpider(scrapy.Spider):
    name = "fengjingt"
    allowed_domains = ["desk.zol.com.cn","baidu.com","inews.gtimg.com"]
    start_urls = ["https://desk.zol.com.cn/fengjing/"]

    def parse(self, response,**kwargs):
        #获取图片url
        lis=response.xpath("//li[@class='photo-list-padding']")
        for li in lis:
            href=li.xpath("./a/@href").extract_first()
            if href.endswith(".exe"):
                continue
            #print(href) #/bizhi/10055_120350_2.html
            #拼接url,使用urljoin,自动对/进行分析,并拼接
            href=response.urljoin(href)
            yield Request(href,callback=self.new_parse)
            break


    def new_parse(self, response, **kwargs):
        src=response.xpath('//*[@id="bigImg"]/@src').extract_first()
        yield {
            'src':src,
        }

pipeline

from scrapy.pipelines.images import ImagesPipeline
from scrapy import Request


class FengjingtuPipeline:
    def process_item(self, item, spider):
        return item

# scrapy提供的图片下载功能
class TupianPipeline(ImagesPipeline):
    #以下3个方法名称固定,都需要重写父类
    # 请求图片的url
    def get_media_requests(self, item, info):
        headers={
            'referer': 'https://desk.zol.com.cn/bizhi/',
            "USER_AGENT": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36"
        }

        src=item["src"]
        src='https://inews.gtimg.com/om_bt/O6SG7dHjdG0kWNyWz6WPo2_3v6A6eAC9ThTazwlKPO1qMAA/641'
        resp=Request(src,meta={'src':src})
        print(resp)
        print(1)
        yield resp

    # 保存图片的路径,scrapy帮我们处理
    def file_path(self, request, response=None, info=None, *, item=None):
        src=request.meta['src']
        file_name=src.split('/')[-1]
        return f'./{file_name}.jpg'
    # 收尾工作
    def item_completed(self, results, item, info):
        pass

设置cookie模拟登录

第一种方式,在settings中添加cookie

如果需要cookie 在settings里设置的不生效,因为scrapy默认中间件有cookie,需要设置一个属性把默认的关闭

测试过程发现 17k小说对 referer要求较高,有时候访问不成功,更换referer后就成功。

并且scrapy有缓存,测试成功后,立马把referer变化,继续运行,依然还可以爬到

第二种方式,在spider中,重写start_request方法,把cookie传过去,cookie需要是字典

第三种方式,直接post方式调用login接口,body需要是字符串,不能是字典,可以用一个库来转换。

自动拼接body过程:

from urllib.parse import urlencode

s=urlencode(data)

手动拼接body过程:

post登录后,回调login_success,然后继续请求,并用scrapy默认方法解析

中间件

中间件是引擎到下载器或引擎到爬虫之间的组件,前者叫下载器中间件,后者叫爬虫中间件,

爬虫中间件用的非常少,不做介绍,主要是下载器中间件。

逻辑图

需要去settings解除中间件注释:

可以有多个中间件,数字越小的,离引擎 越近,优先级越高

模拟每次请求都更换ua

先在settings中放入ua合集

然后去下载器中间件的请求环境设置ua

from settings import headers_list
from random import choice

class MidDownloaderMiddleware:

    def process_request(self, request, spider):
        UserAgent = choice(headers_list)['user-agent']
        request.headers['User-Agent'] = UserAgent
        print(UserAgent)
        return None

结果如下

设置代理ip

在settings添加代理中间件

在middlewares写proxy

class ProxyDownloaderMiddleware:

    def process_request(self, request, spider):
        proxy='183.215.23.242:9091'
        request.meta['proxy'] = f"http://{proxy}"
        return None

分布式爬虫

只需要在spider中改变2处

在settings中做好redis及相关配置

爬虫服务器部署

首先创建虚拟机,并在虚拟机安装scrapyd

然后在客户端安装scrapyd,并修改scrapy.cfg,在终端执行

scrapyd-deploy 部署的地方名 -p 项目名

curl调用接口,执行爬虫

关闭爬虫

容易出现的问题:

访问延时没有开

pipline没有开启

spider,没有写资源的域名,

爬图片的时候,没有配置IMAGE_STORE

如果出现302 记得加上MEDIA_ALLOW_REDIRECTS=True

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tigeraowu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值