Scrapy添加请求头、添加cookie、多个spider顺序运行、pipelines管道

今日是2020.01.01,好日子。写一个文章记录一下scrapy的常用操作。

开始安装2020,新的一年到来了。

>>>pip install 2020
Collecting 2020
  Downloading https://files.pythonhosted.org/packages/2020.whl (2020kB)
     |████████████████████████████████| 2020kB 2020kB/s
Installing collected packages: 2020
Successfully installed 2020-1.0.0

1. 为每一个请求添加请求头

1.1 方法一(直接在settings文件中添加)

settings文件,取消注释DEFAULT_REQUEST_HEADERS,然后在里面添加请求头信息即可。

DEFAULT_REQUEST_HEADERS = {
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Language': 'en',
    'User-Agent':'Mozilla/5.0'
}

1.2 方法二(随机请求头,添加到中间件)

  • 首先在settings文件里边(添加在middlewares也可以)添加一个包含多个user-agent的列表(UA池)。
USER_AGENT_LIST = [
    "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36",
    "Mozilla/5.0 (Linux; U; Android 4.4.2; zh-cn; HUAWEI MT7-TL00 Build/HuaweiMT7-TL00) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
    "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727)",
    "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36 SE 2.X MetaSr 1.0",
    "Mozilla/5.0 (Linux; U; Android 4.1.1; zh-cn; HTC T528t Build/JRO03H) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30; 360browser(securitypay,securityinstalled); 360(android,uppayplugin); 360 Aphone Browser (2.0.4)"
    ]
  • middlewares文件中导入settings里边建立的UA池(如果UA池建立在middlewares则不用导入)
  • 新建一个类,重写process_request该函数即可。
from you_scrapy_project import settings

class UAMiddleware(object):

    def process_request(self, request, spider):
        ua = random.choice(settings.USER_AGENT_LIST)	# 随机获取一个ua
        request.headers['User-Agent'] = ua
  • 最后别忘了去settingsdownloadmiddlewares启动该中间件哦。
DOWNLOADER_MIDDLEWARES = {
    'you_scrapy_project .middlewares.UAMiddleware': 400,
}

2.获取cookie

2.1 方法一(requests.requests.utils.dict_from_cookiejar)

import requests

url = 'https://www.baidu.com'
headers = {
    'user-agent': 'Mozilla/5.0'
	}

resp = requests.get(url, headers=headers)
# 将CookieJar转为字典:
cookie = requests.utils.dict_from_cookiejar(resp.cookies)
print(cookie) #  {'BAIDUID': 'E1A1BC09CC5C0A5BE2AE7A315C55A6C1:FG=1', 'BIDUPSID': 'E1A1BC09CC5C0A5B6E1A2CEC568C2B06', 'PSTM': '1577864887', 'BD_NOT_HTTPS': '1'}

2.2 方法二(selenium的get_cookies())

from selenium import webdriver

url = 'https://www.baidu.com'
driver = webdriver.Chorme()
driver.get(url)
cookie = driver.get_cookies()
print(cookie) # 返回了一大堆数据, 如下
[{'domain': '.baidu.com', 'httpOnly': False, 'name': 'H_PS_PSSID', 'path': '/', 'secure': False, 'value': '1468_21103_30210_30493_30284_26350_22160'}, {'domain': '.baidu.com', 'expiry': 1609401255.26318, 'httpOnly': False, 'name': 'BAIDUID', 'path': '/', 'secure': False, 'value': 'E4B0685C3A0F2F823732B47A077C5010:FG=1'}, {'domain': '.baidu.com', 'expiry': 3725348902.263097, 'httpOnly': False, 'name': 'BIDUPSID', 'path': '/', 'secure': False, 'value': 'E4B0685C3A0F2F82CBE2EB17FB123491'}, {'domain': '.baidu.com', 'httpOnly': False, 'name': 'delPer', 'path': '/', 'secure': False, 'value': '0'}, {'domain': '.baidu.com', 'expiry': 3725348902.263128, 'httpOnly': False, 'name': 'PSTM', 'path': '/', 'secure': False, 'value': '1577865255'}, {'domain': '.baidu.com', 'expiry': 1577951656.419035, 'httpOnly': False, 'name': 'BDORZ', 'path': '/', 'secure': False, 'value': 'B490B5EBF6F3CD402E515D22BCDA1598'}, {'domain': 'www.baidu.com', 'expiry': 1578729256, 'httpOnly': False, 'name': 'BD_UPN', 'path': '/', 'secure': False, 'value': '12314753'}, {'domain': 'www.baidu.com', 'httpOnly': False, 'name': 'BD_HOME', 'path': '/', 'secure': False, 'value': '0'}]

scrapy的cookie只能用 dict 输入,所以需要将这一堆数据转换成字典。


cookie_list = {item['name']:item['value'] for item in cookie}
print(cookie_list) # {'H_PS_PSSID': '1468_21103_30210_30493_30284_26350_22160', 'BAIDUID': 'E4B0685C3A0F2F823732B47A077C5010:FG=1', 'BIDUPSID': 'E4B0685C3A0F2F82CBE2EB17FB123491', 'delPer': '0', 'PSTM': '1577865255', 'BDORZ': 'B490B5EBF6F3CD402E515D22BCDA1598', 'BD_UPN': '12314753', 'BD_HOME': '0'}

3. 为每一个请求添加cookie

3.1 方法一(直接在settings文件中添加)

  • 直接添加到settings文件中即可。
DEFAULT_REQUEST_HEADERS = {
    		'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    		'Accept-Language': 'en',
            'Connection': 'keep-alive',
            'Cookie': 'xxx',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.75 Safari/537.36',
}

3.2 方法二(添加到spider文件中)

  • 如下,将cookie文件添加到spider文件,然后再请求中加上cookie文件即可。
import scrapy

class TransactionSpider(scrapy.Spider):
    name = "you_spider"
    allowed_domains = ['www.xxx.com']
    cookie={
            'Cookie': 'xxx'
            }

	def start_requests(self):
		yield scrapy.Request(url=self.url, cookies=self.cookie, callback=self.parse)

3.3 方法三(添加到中间件)

  • 首先在settings中设置,如下
#COOKIES_ENABLED = False	# 取消注释,并将False更改为True
COOKIES_ENABLED = True		
  • 这里需要重写一个添加cookie的中间件
  • 这里我处理后的以字典形式存在cookie存储到了redis数据库
import redis

# 登录中间件
class AddCookieMiddleware(object):
    def __init__(self):
        self.client = redis.StrictRedis() # '建立redis数据库的连接'
        self.need_add_cookie = {
            'you_spider_01',
            'you_spider_02',
        }								  # '看哪个spider需要添加cookie,就将它添加到这里'
 
    def process_request(self, request, spider):
        # '根据spider.name的名字去判断在不在self.need_add_cookie中,如果存在则添加cookie'
        if spider.name in self.need_add_cookie :
			cookie = self.client.get('cookies')
            request.cookies = cookie
  • 最后别忘了去settingsdownloadmiddlewares启动该中间件哦。
DOWNLOADER_MIDDLEWARES = {
    'you_scrapy_project.middlewares.AddCookieMiddleware': 501,
}

4. 多个spider运行

4.1 多个spider同时运行


4.2 多个spider顺序运行

在scrapy的启动项文件中,如下设置即可按顺序运行。

import os

os.system('scrapy crawl you_spider_01')
os.system('scrapy crawl you_spider_01')

5. Pipelines根据函数名决定走哪个管道

  1. 在spider中会导入items中的类
# spider.py
from you_scrapy_project.items import xxxpipeline	# 需导入全路径

item = xxxpipeline()
item['date'] = xxx
item['name'] = xxx
item['id'] = xxx
yield item
  1. pipelines文件,重写一个管道
from you_scrapy_project.items  import xxxpipeline	# 需导入全路径


class XxxPipeline(object):

    def process_item(self, item, spider):
        if isinstance(item, xxx):
			如果该函数名为xxx,则执行该操作
        elif isinstance(item, ddd):
           如果该函数名为ddd,则执行该操作
        return item
发布了34 篇原创文章 · 获赞 210 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_45081575/article/details/103793985