如何使用axios填写并在另一个网站上提交表格?

如何解决如何使用axios填写并在另一个网站上提交表格?

我当时是用Node.js制作一个抽奖机器人,最初是使用无头Puppeteer来自动完成抽奖表格的提交过程。有人告诉我,Puppeteer占用大量CPU,并且比Node.js中的请求模块(例如fetch,Axios等)慢。

过去2天,我一直在与Axios交流,但我实际上不知道如何填写和提交表单。如何填写和汇总上面在Axios中所述的表格?另外,就速度和CPU使用率而言,Axios是最佳选择吗?还是有更好的选择?

Here is an example for a form I would like to fill in.

这是我填写表格的人偶代码:

const { sizeSelectorsTitolo } = require('./selectors/sizes');
const  accounts  = require('./profiles/savedaccounts');

const { proxyList1 } = require('./profiles/proxylists');



async function titoloMain(url,size,shippingprofile,ppaccountnumber,proxygroup,instaaccountnumber){
    
    let splitProxy = proxygroup.split(':');
    let proxyUserLocal = splitProxy[2];
    let proxyPassLocal = splitProxy[3];
    let proxyPortLocal = splitProxy[1];
    let proxyMainLocal = splitProxy[0];
    let countrySelector = '';
    //Getting size selector ready
    let OurSizeSelector = 'sizeSelectorsTitolo.'
    OurSizeSelector = OurSizeSelector.concat(size);
    delete OurSizeSelector.property;
    OurSizeSelector = eval(OurSizeSelector);
        //Getting country selector
    switch (shippingprofile.country){
        case shippingprofile.country = "UK":
             countrySelector = 'United Kingdom'
                break;
        case shippingprofile.country = "USA":
             countrySelector = 'United States of America'
                break;
        case shippingprofile.country = "France":
             countrySelector = 'France'
                break;
        case shippingprofile.country = "Spain":
            countrySelector = 'Spain'
                break;
        case shippingprofile.country = "Germany":
            countrySelector = 'Germany'
                break;
        case shippingprofile.country = "Canada":
            countrySelector = 'Canada'
                break;                  
        };
        //getting gender selectors
        let localGender = '';
        if (shippingprofile.gender == 'Male'){
            localGender = 'Male'
        } else {
             localGender = 'Female'
        };
    const browser = await puppetteer.launch( {
        headless: true,args: ['--disable-infobars',`--window-size=${1000.},${1000.}`,'--disable-features=IsolateOrigins,site-per-process',//ip and port
        `${proxyMainLocal}:${proxyPortLocal}`
    ],ignoreDefaultArgs: ['--enable-automation']
    });
    const page = await browser.newPage();
        //proxy settings
        await page.authenticate({
            username: proxyUserLocal,password: proxyPassLocal
        });
        await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/84.0.4147.125 Safari/537.36');      
        //now at the raffle page
        console.log('on the raffle page')
        await page.goto(url,{waitUntil:"networkidle2"});
        console.log('filing out form...')
        console.log('paypal')
        await page.waitForSelector('#mce-EMAIL')
        await page.type('#mce-EMAIL',accounts.paypalAccounts[ppaccountnumber].main,{delay:20})
        console.log('name')
        await page.type('#mce-FNAME',shippingprofile.firstname,{delay:20});
        await page.type('#mce-LNAME',shippingprofile.surname,{delay:20});
        console.log('shipping address')
        await page.type('#mce-MMERGE5',shippingprofile.houseNum.concat(` ${shippingprofile.street}`),{delay:20});
        await page.type('#mce-MMERGE8',shippingprofile.postcode,{delay:20});
        await page.type('#mce-MMERGE12',shippingprofile.city,{delay:20});
        await page.select('#mce-MMERGE3',countrySelector);
        console.log('phone number')
        await page.type('#mce-PHONE',shippingprofile.phoneNumber,{delay:20});
        console.log('additional info')
        await page.select('#mce-MMERGE9',localGender);
        await page.select('#mce-MMERGE10','en');
        console.log('instagram name')
        await page.type('#mce-MMERGE7',accounts.instagram[instaaccountnumber].accountname,{delay:20});
        console.log('selecting size')
        await page.select('#mce-MMERGE6',OurSizeSelector)
        console.log('clicking terms')
        await page.waitForSelector('#mce-group\\[199\\]-199-0');
        await page.waitFor(500);
        await page.click('#mce-group\\[199\\]-199-0');
        console.log('submitting')
        await page.click('#mc-embedded-subscribe');
        await page.waitFor(1000);
        console.log(`done,check ${accounts.paypalAccounts[ppaccountnumber].main}`);
        await browser.close()
};

这是axios的代码,我不知道我将如何定位输入字段以发布数据,所以我现在只记录标题:

const axios = require('axios')

async function test() {
    axios.get('https://en.titoloshop.com/titolo/air-jordan-1-retro-high-og-bio-hack/#raffle')
    .then(res => {
        console.log(res.headers)
    })
    .catch(err => {
        if (err.response) {
            console.log('there was an error');
            console.log(err.response.data);
            console.log(err.response.status);
            console.log(err.response.headers);
        }
    });
}

解决方法

TLDR::使用适当的表单数据对表单的POST元素进行适当的编码,以发出action请求。通过查看表单的nameinput元素的select属性,可以找到要发送的密钥。向下滚动查看代码。


首先,了解Puppeteer与请求模块(例如axiosnode-fetch)之间的区别很重要。 Puppeteer用于控制浏览器并像使用用户一样使用网站,而axios仅用于发出HTTP请求。因此,您不能执行诸如单击按钮或填写表格之类的事情。

但是,提交表单通常只是将带有表单数据的HTTP请求发送到另一个URL。例如,这是该抽奖形式的HTML(简化):

<form
  action="https://titolo.us6.list-manage.com/subscribe/post?u=652f80ec0adf2d7ac9588d0a1&id=8093f364b8"
  method="post"
>
  <div>
    <label for="mce-EMAIL">Email Address* (PayPal)</label>
    <input type="email" name="EMAIL" id="mce-EMAIL">
  </div>
  <!-- first name,last name,address,postcode,city -->
  <div>
    <label for="mce-MMERGE3">Country*</label>
    <select name="MMERGE3" id="mce-MMERGE3">
      <option value=""></option>
      <option value="Switzerland">Switzerland</option>
      <!-- more countries... -->
    </select>
  </div>
  <!-- the rest of the inputs... -->
  <div>
    <strong>Terms & Conditions </strong>
      <ul>
        <li>
          <input type="checkbox" name="group[243][1]" id="mce-group[243]-243-0">
          <label for="mce-group[243]-243-0">I agree</label>
        </li>
      </ul>
  </div>
  <!-- more stuff... -->
  <!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
    <div style="position: absolute; left: -5000px">
      <input
        type="text"
        name="b_652f80ec0adf2d7ac9588d0a1_8093f364b8"
        tabindex="-1"
        value=""
      >
    </div>
    <div>
      <input type="submit" value="Subscribe" name="subscribe" id="mc-embedded-subscribe">
    </div>
</form>

让我们分解一下。

  • <form action="..." method="post'>:表单会将帖子主体中的数据POSTaction属性中指定的URL。它将根据enctype属性进行编码。在这种情况下,它将是一个application/x-www-form-urlencoded字符串(例如key1=value1&key2=value2),这是默认设置。
  • <input type="email" name="EMAIL" id="mce-EMAIL">:输入的电子邮件将是帖子正文中的EMAIL键的值(由name属性指示)。
  • <select name="MMERGE3" id="mce-MMERGE3">:所选选项将是MMERGE3键的值。
    • <option value="Switzerland">每个选项都有一个value属性,该属性指定要在帖子正文中发送的字符串。这不必与文本内容相同。如果不存在,则将发送元素的文本内容。
  • <input type="checkbox" value="1" name="group[243][1]" id="mce-group[243]-243-0">这是一个复选框输入。如果选中此复选框,则表单主体中的group[243][1]name属性)将是1value属性,默认为on)。如果未选中,则group[243][1]将不存在。
  • <input type="text" name="b_652f80ec0adf2d7ac9588d0a1_8093f364b8" tabindex="-1" value="">根据评论,这是绝对不能填写的输入,只是为了防止机器人注册抽奖活动(不是讽刺意味?)。
  • <input type="submit" value="Subscribe" name="subscribe" id="mc-embedded-subscribe">这是“提交”按钮。除非存在name属性(就像其他任何input一样),否则不提交此值,因此在这种情况下,将有一个名为subscribe的键,其值为{{1 }}(来自Subscribe属性)。默认的value属性因浏览器而异:
    value

有关提交表单的工作方式的更多信息,请参见Sending form data on MDN


因此,要在不使用Puppeteer的情况下提交此表单,您需要使用适当的URL编码的表单值作为表单数据来发起<input type="submit">请求。您可以在axios(documentation)中进行此操作:

POST

此代码应提交表单,就像用户填写表单并在其网站上提交一样。很有可能,实际上并不是所有这些都需要(例如订阅按钮和不可见的输入),但是为了防万一,我在此包括它们。

注意:网站要求您选择一种希望从公司那里听到的方式:时事通讯(const url = 'https://titolo.us6.list-manage.com/subscribe/post?u=652f80ec0adf2d7ac9588d0a1&id=8093f364b8' axios.post(url,new URLSearchParams({ EMAIL: accounts.paypalAccounts[ppaccountnumber].main,FNAME: shippingprofile.firstname,LNAME: shippingprofile.surname,// Address MMERGE5: shippingprofile.houseNum.concat(` ${shippingprofile.street}`),// Postcode MMERGE8: shippingprofile.postcode,// City MMERGE12: shippingprofile.city,// Country MMERGE3: countrySelector,PHONE: shippingprofile.phoneNumber,// Gender MMERGE9: localGender,// Language MMERGE10: 'en',// Size MMERGE6: OurSizeSelector,// Instagram account name MMERGE7: accounts.instagram[instaaccountnumber].accountname,// T&Cs 'group[243][1]': '1',// That invisible input b_652f80ec0adf2d7ac9588d0a1_8093f364b8: '',// Subscribe button subscribe: 'Subscribe' })) )和/或抽奖信息(name="gdpr[695]")。这两个复选框都具有name="gdpr[699]",因此,如果要作为表单的一部分提交这些复选框,只需将value="Y"和/或'gdpr[695]': 'Y'添加到'gdpr[699]': 'Y'构造函数中。>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-