scrapy完整版重写start_requests方法 python requests 强大用法

本文介绍了如何在Scrapy中重写start_requests方法以处理不同需求,如设置header、cookie、data,以及如何携带data数据进行POST请求。此外,还讲解了如何使用FormRequest从响应中自动提取表单POST地址,并设置了代理和随机选择请求头。最后提到了在Scrapy中结合selenium处理难以爬取的页面。
部署运行你感兴趣的模型镜像

scrapy第一次请求方式的重写

# -*- coding: utf-8 -*-
import scrapy
from ..items import MaoyanItem


class MaoyanSpider(scrapy.Spider):
    name = 'maoyan3'
    allowed_domains = ['maoyan.com']

    #重写start_requests()方法,把所有URL地址都交给调度器
    def start_requests(self):
        # 把所有的URL地址统一扔给调度器入队列
        for offset in range(0, 91, 10):
            url = 'https://maoyan.com/board/4?offset={}'.format(offset)
            # 交给调度器
            yield scrapy.Request(
                url=url,
                callback=self.parse_html
            )

    def parse_html(self,response):
        #基准的xpath
        dd_list = response.xpath('//dl[@class="board-wrapper"]/dd')
        #for循环依次遍历
        for dd in dd_list:
            #创建对象'
            item = MaoyanItem()
            # 电影名称
            # 如果不添加extract_first(),会得到一堆列表里面的选择器,但是我们的目标是得到字符串
            item["name"] = dd.xpath("./a/@title").extract_first().strip()
            # 电影主演
            item["star"] = dd.xpath(".//p[@class='star']/text()").extract_first().strip()
            #上映时间
            item["time"] = dd.xpath('.//p[@class="releasetime"]/text()').extract_first().strip()

            #把爬取的数据交给管道文件pipeline处理
            #生成器
            yield item

当起始请求需要设置header,cookie,data时,则要对起始请求做处理,所以需要重写第一次请求处理函数start_request(self)

1 设置header与cookie

    如果在settings.py文件中设置请求头,则所有的蜘蛛文件都使用该请求头,然而不同的蜘蛛文件需要不同的请求头,因此需要给每个蜘蛛文件的请求设置独立的请求头.

    设置独立的header和cookie方法为在蜘蛛文件中重写第一次请求处理方法start_requests

    例:
    # 重写第一次请求处理函数,要返回Request对象
    def start_requests(self):
        start_url = '要请求的链接'
        headers = {}
        cookies = {}
        yield scrapy.Request(url=start_url, headers=headers,callback=self.parse,cookies=cookies)
    scrapy.Request函数还有一个meta参数,值为字典格式,作用是携带数据在指定的回调函数中使用,使用方法:response.meta['键']

2 携带data数据

    同样重写start_requests方法,返回FormRequest对象,此时请求方式为post

    例: 


    def start_requests(self):
        login_url = '要请求的链接'
        # 发送post请求
        data = {}
        yield scrapy.FormRequest(url=login_url,formdata=data,callback=self.after_login)
    scrapy.FormRequest.from_response方法可以从响应中自动提取表单POST地址,例如处理登录,需要先返回登录页面,再填充表单,然后提交  


    # 自动提取表单post地址    
    yield scrapy.FormRequest.from_response(
        response,
        headers=self.header,
        formdata=data,
        callback=self.after_login,
    )
3 设置代理与随机选择请求头

        通过下载器中间件来设置请求.

        免费代理:

1
    request.meta['proxy'] = 'http://' + '代理IP'


        收费代理:需要先将账号密码base64编码,再设置给request,然后设置request.meta['proxy']:
    auth = base64.b64encode({'帐号':'密码'})  #base64需要导入
    request.headers['Proxy-Authorization'] = 'Basic ' + auth
    request.meta['proxy'] = 'http://' + '代理IP'


        例:
    #coding:utf8    
    from settings import USER_AGENS,PROXIES
    import random
    import base64
     
    # 随机更换浏览器身份中间件
    class RandomUserAgent(object):
        def process_request(self,request,spider):
            user_agent = random.choice(USER_AGENS)
            request.headers.setdefault('User-Agent',user_agent)
     
    # 随机更换代理ip
    class RandomProxy(object):
        def process_request(self,request , spider):
            proxy = random.choice(PROXIES) # 随机选出一个代理
            if proxy.get('auth') is None: # 免费代理
                request.meta['proxy'] = 'http://' + proxy['host']
            else : # 收费代理
                auth = base64.b64encode(proxy['auth'])
                request.headers['Proxy-Authorization'] = 'Basic ' + auth
                request.meta['proxy'] = 'http://' + proxy['host']

4 在scrapy中使用selenium

    如果有些页面实在难以爬取,可以使用selenium方式,但是此方式会慢,所以尽量去抓包解析页面结构爬取.

    使用: 在下载器中间件中,截取request,使用selenium对request的url发送请求,将获取的response返回,不使用下载器发送请求.

 python requests  强大用法

#! /usr/bin/env python
# -*- coding=utf-8 -*-

import json
import requests
import re
from lxml import etree
from time import sleep
from random import randint
import multiprocessing
import time
import numpy as np
 
headers = {
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"
}

def runSpider(url):
    color=randint(31,37)
    try:
        rep = requests.get(url,headers=headers)
        if rep.status_code != 200:
            runSpider(url)
            return
        et_html = etree.HTML(rep.text)
        urls = et_html.xpath("//div[@class='article-item-box csdn-tracking-statistics']//@href")
        print(urls)
        if urls:
            for i in urls:
                try:
                    rep = requests.get(i,headers=headers)
                except Exception as e:
                    print("\033[1;{}m Error: {} >>> {}\033[0m".format(color,i,e))
                sleep(randint(5,50))
                print(i)
    except Exception as e:
        print("\033[1;36m ListUrl Error: {} \033[0m".format(color,e))


def start(msg):
    while True:
        startUrl="https://blog.youkuaiyun.com/sirobot/article/list/{}"
        n = randint(1,7)
        color=randint(31,37)
        Pn=multiprocessing.current_process().name + '-' + msg
        print("\033[1;{}m  ProcessName: {} >>> Page: {}\033[0m".format(color,Pn,n))
        startUrl=startUrl.format(str(n))
        print(startUrl)
        try:
            runSpider(startUrl)
            print(startUrl)
        except Exception as e:
            print("\033[1;{}m startUrl Error: {} \033[0m".format(color,e))
        sleep(randint(30,100))

if __name__ == "__main__":
    
    pool = multiprocessing.Pool(processes=5) #
    results = []
    inx=np.random.randint(5689,6985486,size=[1,8])
    for i in inx[0]:
        msg = "inx %d" %(i)
        results.append(pool.apply_async(start, (msg, )))
    pool.close() 
    pool.join() 
    print ("Sub-process(es) done.")

    for res in results:
        print (res.get())

 

您可能感兴趣的与本文相关的镜像

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值