Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/445.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用木偶演员通过文本进行选择_Javascript_Forms_Web Scraping_Puppeteer - Fatal编程技术网

Javascript 使用木偶演员通过文本进行选择

Javascript 使用木偶演员通过文本进行选择,javascript,forms,web-scraping,puppeteer,Javascript,Forms,Web Scraping,Puppeteer,正在编写一个脚本,该脚本将使用木偶演员在开球时间可用时预订开球时间。如果我有一个我知道我想预订的特定日期,我想知道是否有一个在datepicker中选择该日期的好方法(所有日期都有一个类“day”,但不能单独识别)。这是一个没有输入的日期选择器,在一个我不控制日期选择器的站点上。我只想能够填写表格,并作出适当的选择,但所有的日期有相同的选择器。我在附上一张日期选取者的照片。选择提前7天的日期的最佳方式是什么 理论上 您可以使用page.$eval和page.$$eval方法收集日历内容: con

正在编写一个脚本,该脚本将使用木偶演员在开球时间可用时预订开球时间。如果我有一个我知道我想预订的特定日期,我想知道是否有一个在datepicker中选择该日期的好方法(所有日期都有一个类“day”,但不能单独识别)。这是一个没有输入的日期选择器,在一个我不控制日期选择器的站点上。我只想能够填写表格,并作出适当的选择,但所有的日期有相同的选择器。我在附上一张日期选取者的照片。选择提前7天的日期的最佳方式是什么

理论上 您可以使用
page.$eval
page.$$eval
方法收集日历内容:

const calMonthYear = await page.$eval('.calendar-monthname', month => month.innerText)
// September 2020

const calDays = await page.$$eval('.calendar-grid > ul > li', days => days.map(d => d.innerText))
// ["30", "31", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "1", "2", "3"]
注意:在最后一个示例中,我使用
let
声明它们,因为一旦我们必须在日期选择上转到下个月,它们就需要重新声明

然后,如果指定日期,则可以使每个日历日元素成为有效的JavaScript日期对象,例如:

Date.parse(`${calDays[10]} ${calMonthYear}`) // 9 September 2020
// 1599602400000
当前日期(今天)总是有一个特定的类名,例如:
。选择
,我们可以使用Puppeter评估它的日期(假设这是有效的“现在”,而不是
日期。现在()

我们可以创建一个希望以历元格式选择的日期(应该是
date.parse()
-ed):

最后,您应该编写一个迭代,以在7天后选择所需的元素,如下所示:

[...]

let calendarGridItemCount =  await page.$$eval('.calendar-grid > ul > li', el => el.length)
let calMonthYear = await page.$eval('.calendar-monthname', month => month.innerText)
let calDays = await page.$$eval('.calendar-grid > ul > li', days => days.map(d => d.innerText))

const wantedDate = Date.parse(sevenDaysLater)

  for (let i = 0; i < calendarGridItemCount; i++) {
    let examinedCalendarGridItem = Date.parse(`${calDays[i]} ${calMonthYear}`)
    if (examinedCalendarGridItem == wantedDate) {
      const dayFound = (await page.$$('.calendar-grid > ul > li'))[i]
      await dayFound.click()
      break
    } else if (examinedCalendarGridItem !== wantedDate && i === calendarGridItemCount - 1) {
      await page.click('.calendar-next')
      calendarGridItemCount = await page.$$eval('.calendar-grid > ul > li', el => el.length)
      calMonthYear = await page.$eval('.calendar-monthname', month => month.innerText)
      calDays = await page.$$eval('.calendar-grid > ul > li', days => days.map(d => d.innerText))
      i = 0
      continue
    }
  }
[…]
让calendarGridItemCount=等待页面。$$eval('.calendar grid>ul>li',el=>el.length)
让calMonthYear=等待页面。$eval('.calendar monthname',month=>month.innerText)
让calDays=wait page.$$eval('.calendar grid>ul>li',days=>days.map(d=>d.innerText))
const wantedDate=Date.parse(sevenDaysLater)
for(设i=0;iul>li'))[i]
等待找到日期。单击()
打破
}else if(检查的CalendarGridItem!==wantedDate&&i===calendarGridItemCount-1){
等待页面。单击(“.日历下一步”)
calendarGridItemCount=等待页面。$$eval('.calendar grid>ul>li',el=>el.length)
calMonthYear=等待页面。$eval('.calendar monthname',month=>month.innerText)
calDays=等待页面。$$eval('.calendar grid>ul>li',days=>days.map(d=>d.innerText))
i=0
持续
}
}
确保:
  • 当+7天的日期在下个月时,您可以处理这些情况(使用
    .calendar next
    按钮转到下个月)
  • 处理孤立日(无论是在月初还是月末……如果月末的孤立日是可选择的,则这不是问题)例如:您可以在保留索引的情况下清除
    calDays
    数组中孤立日的值(迭代中需要索引来确定可选择的日期,将过去的日期分割会打乱它们的顺序)

您是否也可以共享其HTML源代码的示例片段(或页面的url,如果它是公共的)?最好看看当前日期是否至少有一个唯一的类(我确信它有一个)。选定的日期也有“选定”的类…默认情况下从当天开始…但除此之外,除了前几天被禁用外,没有任何内容指示哪一天是当天。url位于会员墙后面…但我可以共享HTML片段(或屏幕截图)如果您能告诉我哪些部分会有帮助。@驾驶员如果标记的数量不是那么大,最好至少看到包含月份名称的元素,以及:一个过去日期,一个可选择的日期元素(例如9月10日)以及类为
的元素。选中了
。大多数情况下,日历元素可以使用与创建时相同的逻辑进行迭代,这就是为什么查看如何将其放入HTML(或者是否有任何其他有用的属性,如onclick events等)很有帮助的原因谢谢David。非常有用。日历没有列表,只有表行,但是这种方法非常有用。我会尽快尝试它。是的,它应该以同样的方式与表-s一起工作。我没有运行脚本,所以我犯了一些错误,我现在已经纠正了。(1)不要忘记解析wantedDate
const wantedDate=Date.parse(sevenDaysLater)
和(2)我在键入
页面时出现语法错误。$eval
-s多次,现在它们也被修复了。我建议检查我对代码的最新编辑。你能在@toddmetheny尝试一下吗?嘿,大卫,我没有。那是一个个人项目,我有一些其他事情要做,还没有回复。我可以继续批准,不是吗霍,所以我不会忘记。谢谢你的帮助!
const todayIndex = calDays.indexOf(calToday)
// 10

const todayEpoch = Date.parse(`${calDays[todayIndex]} ${calMonthYear}`) // 9 September 2020
// 1599602400000
let today = new Date(todayEpoch)
let sevenDaysLater = new Date()
sevenDaysLater.setDate(today.getDate() + 7)
sevenDaysLater.setHours(0,0,0,0)
// 1600207200000  (Wed Sep 16 2020 00:00:00 GMT+0200 (Central European Summer Time))
[...]

let calendarGridItemCount =  await page.$$eval('.calendar-grid > ul > li', el => el.length)
let calMonthYear = await page.$eval('.calendar-monthname', month => month.innerText)
let calDays = await page.$$eval('.calendar-grid > ul > li', days => days.map(d => d.innerText))

const wantedDate = Date.parse(sevenDaysLater)

  for (let i = 0; i < calendarGridItemCount; i++) {
    let examinedCalendarGridItem = Date.parse(`${calDays[i]} ${calMonthYear}`)
    if (examinedCalendarGridItem == wantedDate) {
      const dayFound = (await page.$$('.calendar-grid > ul > li'))[i]
      await dayFound.click()
      break
    } else if (examinedCalendarGridItem !== wantedDate && i === calendarGridItemCount - 1) {
      await page.click('.calendar-next')
      calendarGridItemCount = await page.$$eval('.calendar-grid > ul > li', el => el.length)
      calMonthYear = await page.$eval('.calendar-monthname', month => month.innerText)
      calDays = await page.$$eval('.calendar-grid > ul > li', days => days.map(d => d.innerText))
      i = 0
      continue
    }
  }