Python爬虫:scrapy框架请求参数meta、headers、cookies一探究竟(1)

简介: Python爬虫:scrapy框架请求参数meta、headers、cookies一探究竟(1)

对于scrapy请参数,会经常用到,不过没有深究


今天我就来探索下scrapy请求时所携带的3个重要参数headers, cookies, meta


原生参数

首先新建myscrapy项目,新建my_spider爬虫


通过访问:http://httpbin.org/get 来测试请求参数


将爬虫运行起来


# -*- coding: utf-8 -*-
from scrapy import Spider, Request
import logging
class MySpider(Spider):
    name = 'my_spider'
    allowed_domains = ['httpbin.org']
    start_urls = [
        'http://httpbin.org/get'
    ]
    def parse(self, response):
        self.write_to_file("*" * 40)
        self.write_to_file("response text: %s" % response.text)
        self.write_to_file("response headers: %s" % response.headers)
        self.write_to_file("response meta: %s" % response.meta)
        self.write_to_file("request headers: %s" % response.request.headers)
        self.write_to_file("request cookies: %s" % response.request.cookies)
        self.write_to_file("request meta: %s" % response.request.meta)
    def write_to_file(self, words):
        with open("logging.log", "a") as f:
            f.write(words)
if __name__ == '__main__':
    from scrapy import cmdline
    cmdline.execute("scrapy crawl my_spider".split())

保存到文件中的信息如下:


response text: 
{
    "args":{},
    "headers":{
        "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
        "Accept-Encoding":"gzip,deflate",
        "Accept-Language":"en",
        "Connection":"close",
        "Host":"httpbin.org",
        "User-Agent":"Scrapy/1.5.1 (+https://scrapy.org)"
    },
    "origin":"223.72.90.254",
    "url":"http://httpbin.org/get"
}
response headers: 
{
    b'Server': [b'gunicorn/19.8.1'], 
    b'Date': [b'Sun, 22 Jul 2018 10:03:15 GMT'], 
    b'Content-Type': [b'application/json'], 
    b'Access-Control-Allow-Origin': [b'*'], 
    b'Access-Control-Allow-Credentials': [b'true'], 
    b'Via': [b'1.1 vegur']
}
response meta: 
{
    'download_timeout': 180.0, 
    'download_slot': 'httpbin.org', 
    'download_latency': 0.5500118732452393
}
request headers: 
{
    b'Accept': [b'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'], b'Accept-Language': [b'en'], 
    b'User-Agent': [b'Scrapy/1.5.1 (+https://scrapy.org)'], 
    b'Accept-Encoding': [b'gzip,deflate']
}
request cookies: 
{}
request meta: 
{
    'download_timeout': 180.0, 
    'download_slot': 'httpbin.org', 
    'download_latency': 0.5500118732452393
}

meta

通过上面的输出比较,发现 response 和 request 的meta参数是一样的,meta的功能就是从request携带信息,将其传递给response的


修改下代码,测试下传递效果


# -*- coding: utf-8 -*-
from scrapy import Spider, Request
import logging
class MySpider(Spider):
    name = 'my_spider'
    allowed_domains = ['httpbin.org']
    start_urls = [
        'http://httpbin.org/get'
    ]
    def start_requests(self):
        for url in self.start_urls:
            yield Request(url, meta={"uid": "this is uid of meta"})
    def parse(self, response):
        print("request meta: %s" % response.request.meta.get("uid"))
        print("response meta: %s" % response.meta.get("uid"))

输出如下


request meta: this is uid of meta
response meta: this is uid of meta

看来获取request中meta这两种方式都可行,这里的meta类似字典,可以按照字典获取key-value的形式获取对应的值

当然代理设置也是通过meta的

以下是一个代理中间件的示例


import random
class ProxyMiddleware(object):       
    def process_request(self, request, spider):
        proxy=random.choice(proxies)
        request.meta["proxy"] = proxy

headers

按照如下路径,打开scrapy的default_settings文件


from scrapy.settings import default_settings

发现是这么写的

USER_AGENT = 'Scrapy/%s (+https://scrapy.org)' % import_module('scrapy').__version__
DEFAULT_REQUEST_HEADERS = {
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Language': 'en',
}

修改下请求头,看服务器返回的信息


# -*- coding: utf-8 -*-
from scrapy import Spider, Request
import logging
class MySpider(Spider):
    name = 'my_spider'
    allowed_domains = ['httpbin.org']
    start_urls = [
        'http://httpbin.org/get',
    ]
    def start_requests(self):
        for url in self.start_urls:
            yield Request(url, headers={"User-Agent": "Chrome"})
    def parse(self, response):
        logging.debug("*" * 40)
        logging.debug("response text: %s" % response.text)
        logging.debug("response headers: %s" % response.headers)
        logging.debug("request headers: %s" % response.request.headers)
if __name__ == '__main__':
    from scrapy import cmdline
    cmdline.execute("scrapy crawl my_spider".split())

输出如下


response text: 
{
    "args":{},
    "headers":
    {
        "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
        "Accept-Encoding":"gzip,deflate",
        "Accept-Language":"en",
        "Connection":"close",
        "Host":"httpbin.org",
        "User-Agent":"Chrome"
    },
    "origin":"122.71.64.121",
    "url":"http://httpbin.org/get"
}
response headers: 
{
    b'Server': [b'gunicorn/19.8.1'], 
    b'Date': [b'Sun, 22 Jul 2018 10:29:26 GMT'], 
    b'Content-Type': [b'application/json'], 
    b'Access-Control-Allow-Origin': [b'*'], 
    b'Access-Control-Allow-Credentials': [b'true'], 
    b'Via': [b'1.1 vegur']
}
request headers: 
{
    b'User-Agent': [b'Chrome'], 
    b'Accept': [b'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'], b'Accept-Language': [b'en'], 
    b'Accept-Encoding': [b'gzip,deflate']
}

看到 request 和 服务器接收到并返回的的 headers(User-Agent)变化了,说明已经把默认的User-Agent修改了


看到default_settings中默认使用了中间件UserAgentMiddleware


'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': 500,

源码如下


class UserAgentMiddleware(object):
    """This middleware allows spiders to override the user_agent"""
    def __init__(self, user_agent='Scrapy'):
        self.user_agent = user_agent
    @classmethod
    def from_crawler(cls, crawler):
        o = cls(crawler.settings['USER_AGENT'])
        crawler.signals.connect(o.spider_opened, signal=signals.spider_opened)
        return o
    def spider_opened(self, spider):
        self.user_agent = getattr(spider, 'user_agent', self.user_agent)
    def process_request(self, request, spider):
        if self.user_agent:
            request.headers.setdefault(b'User-Agent', self.user_agent)

仔细阅读源码,发现无非就是对User-Agent读取和设置操作,仿照源码写自己的中间件


这里使用fake_useragent库来随机获取请求头,详情可参看:

https://blog.csdn.net/mouday/article/details/80476409


middlewares.py 编写自己的中间件


from fake_useragent import UserAgent
class UserAgentMiddleware(object):
    def process_request(self, request, spider):
        ua = UserAgent()
        user_agent = ua.chrome
        request.headers.setdefault(b'User-Agent', user_agent)

settings.py 用自己的中间件替换默认中间件


DOWNLOADER_MIDDLEWARES = {
    'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None,
    'myscrapy.middlewares.UserAgentMiddleware': 500
}

输出如下:

request headers: 
{
    b'Accept': [b'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'], b'Accept-Language': [b'en'], 
    b'User-Agent': [b'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.93 Safari/537.36'], 
    b'Accept-Encoding': [b'gzip,deflate']
}

关于scrapy请求头设置,可以参考我之前的文章:

https://blog.csdn.net/mouday/article/details/80776030

相关文章
|
17天前
|
数据采集 Python
【python】爬虫-西安医学院-校长信箱
本文以西安医学院-校长信箱为基础来展示爬虫案例。来介绍python爬虫。
【python】爬虫-西安医学院-校长信箱
|
23天前
|
数据采集 安全 Python
python并发编程:Python实现生产者消费者爬虫
python并发编程:Python实现生产者消费者爬虫
24 0
python并发编程:Python实现生产者消费者爬虫
|
1月前
|
数据采集 数据挖掘 调度
异步爬虫实践攻略:利用Python Aiohttp框架实现高效数据抓取
本文介绍了如何使用Python的Aiohttp框架构建异步爬虫,以提升数据抓取效率。异步爬虫利用异步IO和协程技术,在等待响应时执行其他任务,提高效率。Aiohttp是一个高效的异步HTTP客户端/服务器框架,适合构建此类爬虫。文中还展示了如何通过代理访问HTTPS网页的示例代码,并以爬取微信公众号文章为例,说明了实际应用中的步骤。
|
3天前
|
数据采集 存储 JSON
Python爬虫面试:requests、BeautifulSoup与Scrapy详解
【4月更文挑战第19天】本文聚焦于Python爬虫面试中的核心库——requests、BeautifulSoup和Scrapy。讲解了它们的常见问题、易错点及应对策略。对于requests,强调了异常处理、代理设置和请求重试;BeautifulSoup部分提到选择器使用、动态内容处理和解析效率优化;而Scrapy则关注项目架构、数据存储和分布式爬虫。通过实例代码,帮助读者深化理解并提升面试表现。
12 0
|
6天前
|
数据采集 JavaScript 前端开发
使用Python打造爬虫程序之破茧而出:Python爬虫遭遇反爬虫机制及应对策略
【4月更文挑战第19天】本文探讨了Python爬虫应对反爬虫机制的策略。常见的反爬虫机制包括User-Agent检测、IP限制、动态加载内容、验证码验证和Cookie跟踪。应对策略包括设置合理User-Agent、使用代理IP、处理动态加载内容、验证码识别及维护Cookie。此外,还提到高级策略如降低请求频率、模拟人类行为、分布式爬虫和学习网站规则。开发者需不断学习新策略,同时遵守规则和法律法规,确保爬虫的稳定性和合法性。
|
17天前
|
数据采集 存储 前端开发
Python爬虫如何快速入门
写了几篇网络爬虫的博文后,有网友留言问Python爬虫如何入门?今天就来了解一下什么是爬虫,如何快速的上手Python爬虫。
20 0
|
1月前
|
数据采集 存储 Web App开发
一键实现数据采集和存储:Python爬虫、Pandas和Excel的应用技巧
一键实现数据采集和存储:Python爬虫、Pandas和Excel的应用技巧
|
1月前
|
数据采集 前端开发 JavaScript
Python爬虫零基础到爬啥都行
Python爬虫项目实战全程实录,你想要什么数据能随意的爬,不管抓多少数据几分钟就能爬到你的硬盘,需要会基本的前端技术(HTML、CSS、JAVASCRIPT)和LINUX、MYSQL、REDIS基础。
20 1
Python爬虫零基础到爬啥都行
|
1月前
|
数据采集 Web App开发 搜索推荐
项目配置之道:优化Scrapy参数提升爬虫效率
项目配置之道:优化Scrapy参数提升爬虫效率
|
13天前
|
数据采集 存储 API
网络爬虫与数据采集:使用Python自动化获取网页数据
【4月更文挑战第12天】本文介绍了Python网络爬虫的基础知识,包括网络爬虫概念(请求网页、解析、存储数据和处理异常)和Python常用的爬虫库requests(发送HTTP请求)与BeautifulSoup(解析HTML)。通过基本流程示例展示了如何导入库、发送请求、解析网页、提取数据、存储数据及处理异常。还提到了Python爬虫的实际应用,如获取新闻数据和商品信息。