Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python
- from datetime import time, date, datetime, timedelta
- from time import sleep
- from json import loads
- from lxml import etree
- from requests import Session, exceptions
- import re
- username=''
- password=''
- #location='Barendrecht (Zwaalweg 1)'
- location='' # 'Breda (Heerbaan 4)' # Can be empty
- product='' # 'BTH' # Can be empty
- start_time="14:00"
- end_time='' # Can be empty
- start=date.today()+timedelta(days=18)
- end=start+timedelta(weeks=3)
- # start=date.today()+timedelta(weeks=4)
- # end=start+timedelta(days=5)
- postfix='{} {}-{}'.format(username, start_time, end_time).replace(':','.')
- f=open(postfix+'.log','w')
- # Prepare the data before to save time within the request
- buying_data={
- "ctl00$ctl00$DefaultContent$DefaultContent$Divisions$referenceDataCombobox_Divisions": "DIVISIE AFNAME THEORIE",
- "ctl00$ctl00$DefaultContent$DefaultContent$ExamTimeFrom": start_time,
- "ctl00$ctl00$DefaultContent$DefaultContent$ExamTimeUpToInclusive": end_time,
- "ctl00$ctl00$DefaultContent$DefaultContent$Find.x": "33",
- "ctl00$ctl00$DefaultContent$DefaultContent$Find.y": "38",
- "ctl00$ctl00$DefaultContent$DefaultContent$IncludeFridays": "on",
- "ctl00$ctl00$DefaultContent$DefaultContent$IncludeMondays": "on",
- "ctl00$ctl00$DefaultContent$DefaultContent$IncludeSaturdays": "on",
- "ctl00$ctl00$DefaultContent$DefaultContent$IncludeThursdays": "on",
- "ctl00$ctl00$DefaultContent$DefaultContent$IncludeTuesdays": "on",
- "ctl00$ctl00$DefaultContent$DefaultContent$IncludeWednesdays": "on",
- "ctl00$ctl00$MasterScriptManager": "ctl00$ctl00$MasterScriptManager|ctl00$ctl00$DefaultContent$DefaultContent$Find",
- "ctl00_ctl00_DefaultContent_DefaultContent_ExamDateFromDatePicker_dateInput_ClientState": '{{"enabled":true,"emptyMessage":"","validationText":"{0.year}-{0.month:02d}-{0.day:02d}-00-00-00","valueAsString":"{0.year}-{0.month:02d}-{0.day:02d}-00-00-00","minDateStr":"1000-01-01-00-00-00","maxDateStr":"2099-12-31-00-00-00","lastSetTextBoxValue":"{0.day:02d}-{0.month:02d}-{0.year}"}}'.format(start),
- "ctl00_ctl00_DefaultContent_DefaultContent_ExamDateUpToDatePicker_dateInput_ClientState": '{{"enabled":true,"emptyMessage":"","validationText":"{0.year}-{0.month:02d}-{0.day:02d}-00-00-00","valueAsString":"{0.year}-{0.month:02d}-{0.day:02d}-00-00-00","minDateStr":"1000-01-01-00-00-00","maxDateStr":"2099-12-31-00-00-00","lastSetTextBoxValue":"{0.day:02d}-{0.month:02d}-{0.year}"}}'.format(end),
- 'ctl00_ctl00_DefaultContent_DefaultContent_ExamDateFromDatePicker_ClientState': '{"minDateStr":"1000-01-01-00-00-00","maxDateStr":"2099-12-31-00-00-00"}',
- 'ctl00_ctl00_DefaultContent_DefaultContent_ExamDateUpToDatePicker_ClientState': '{"minDateStr":"1000-01-01-00-00-00","maxDateStr":"2099-12-31-00-00-00"}',
- 'ctl00_ctl00_DefaultContent_DefaultContent_ExamDateUpToDatePicker_calendar_AD': '[[2016,7,19],[2099,12,30],[2016,8,1]]',
- 'ctl00_ctl00_DefaultContent_DefaultContent_ExamDateUpToDatePicker_calendar_SD': '[[2016,8,9]]',
- "ctl00$ctl00$DefaultContent$DefaultContent$ExamDateFromDatePicker": "{0.year}-{0.month:02d}-{0.day:02d}".format(start),
- "ctl00$ctl00$DefaultContent$DefaultContent$ExamDateFromDatePicker$dateInput": "{0.day:02d}-{0.month:02d}-{0.year}".format(start),
- "ctl00$ctl00$DefaultContent$DefaultContent$ExamDateUpToDatePicker": "{0.year}-{0.month:02d}-{0.day:02d}".format(end),
- "ctl00$ctl00$DefaultContent$DefaultContent$ExamDateUpToDatePicker$dateInput": "{0.day:02d}-{0.month:02d}-{0.year}".format(end),
- "ctl00_ctl00_DefaultContent_DefaultContent_ExamDateFromDatePicker_calendar_AD": "[[{0.year},{0.month},{0.day}],[2099,12,30],[{0.year},{0.month},{0.day}]]".format(start),
- "ctl00_ctl00_DefaultContent_DefaultContent_ExamDateUpToDatePicker_calendar_AD": "[[{0.year},{0.month:02d},{0.day:02d}],[2099,12,30],[{0.year},{0.month:02d},{0.day:02d}]]".format(end),
- '__EVENTARGUMENT': '',
- '__EVENTTARGET': '',
- }
- get_loc_ids=False # Update the location file
- num_xpath=etree.XPath('table/tr/td[7]/text()') # number of available exams
- inputs_xpath=etree.XPath('//form[@name="aspnetForm"]//input')
- examrows_xpath=etree.XPath('//div[@class="gridSingleRow"]')
- inputs_re=re.compile(r'<input (?:{pair})*name={val} (?:{pair})*value={val} (?:{pair})*/>'.format(pair='[a-z]+="(?:[^"]*)" ', val='"([^"]*)"'), re.A)
- url='https://top.cbr.nl/Top/Reservation/BuyCapacityView.aspx'
- s=Session()
- parser=etree.HTMLParser()
- etree.set_default_parser(parser)
- s.headers.update({
- 'User-Agent': 'Mozilla/5.0 (X11, Linux x86_64, rv:47.0) Gecko/20100101 Firefox/47.0',
- 'Accept': 'text/html,application/xhtml+xml,application/xml,q=0.9,*/*,q=0.8',
- 'Accept-Encoding': 'gzip, deflate, br',
- })
- def init(tree):
- return {i.attrib['name']:i.attrib['value'] for i in inputs_xpath(tree) if 'value' in i.attrib}
- def init_re(text):
- res={}
- for line in text.splitlines():
- while True:
- m=inputs_re.search(line)
- if not m: break
- g=m.groups()
- res[g[0]]=g[1]
- line=line[m.end():]
- return res
- def getvals(tree, ctl):
- d=init(tree)
- d.update({
- '__CALLBACKID': ctl,
- '__CALLBACKPARAM': '{"Command":"LOD","ClientState":{"value":"*", "text":"(alles)"}}',
- })
- r=s.post(url, data=d)
- j=loads(r.text[r.text.find('['):r.text.find(']')+1])
- return {i['text']:i['value'] for i in j}
- # tosleep=datetime.combine(date.today()+timedelta(days=1), time(6,59,50))-datetime.now()
- # tosleep=tosleep.seconds
- # print(tosleep)
- # sleep(tosleep)
- loc_ids={}
- with open('loc_ids.lst') as fi:
- for i in fi:
- loc,code=i.strip().split('\t')
- loc_ids[loc]=code
- print(len(loc_ids),'locations', file=f)
- #for _ in range(0):
- while True:
- try:
- r=s.get('https://top.cbr.nl/Top/LogOnView.aspx')
- except Exception as e:
- #print('Exception',e)
- continue
- #print(r.status_code, len(r.text))
- if len(r.text) > 2000: break
- timestamp_s=datetime.now()
- print('Connected: {}'.format(timestamp_s), file=f)
- # import timeit
- # print(timeit.timeit(lambda: etree.fromstring(r.text), number=1000))
- # print(timeit.timeit(lambda: init_re(r.text), number=1000))
- # exit()
- # data=init(etree.fromstring(r.text))
- data=init_re(r.text)
- data.update({
- '__EVENTTARGET': 'ctl00$ctl00$ctl00$DefaultContent$DefaultContent$DefaultContent$LogOn',
- 'ctl00$ctl00$ctl00$DefaultContent$DefaultContent$DefaultContent$LogOnUserName': username,
- 'ctl00$ctl00$ctl00$DefaultContent$DefaultContent$DefaultContent$LogOnPassword': password
- })
- r=s.post('https://top.cbr.nl/Top/LogOnView.aspx', data=data)
- r=s.get(url)
- tree=etree.fromstring(r.text)
- if product:
- pg_ids=getvals(tree, 'ctl00$ctl00$DefaultContent$DefaultContent$ProductGroups$referenceDataCombobox_ProductGroups')
- d=init(tree)
- d.update({
- '__EVENTTARGET': 'ctl00$ctl00$DefaultContent$DefaultContent$ProductGroups$referenceDataCombobox_ProductGroups',
- 'ctl00_ctl00_DefaultContent_DefaultContent_ProductGroups_referenceDataCombobox_ProductGroups_ClientState': '{"value":"'+pg_ids[product]+'"}'
- })
- r=s.post(url, data=d)
- tree=etree.fromstring(r.text)
- if location:
- if get_loc_ids:
- loc_ids=getvals(tree, 'ctl00$ctl00$DefaultContent$DefaultContent$Locations$referenceDataCombobox_Locations')
- d=init(tree)
- d.update({
- '__EVENTTARGET': 'ctl00$ctl00$DefaultContent$DefaultContent$Locations$referenceDataCombobox_Locations',
- 'ctl00_ctl00_DefaultContent_DefaultContent_Locations_referenceDataCombobox_Locations_ClientState': '{"logEntries":[],"value":"__expandcollapse","text":"toon alles","enabled":true,"checkedIndices":[],"checkedItemsTextOverflows":false}'
- })
- r=s.post(url, data=d)
- tree=etree.fromstring(r.text)
- loc_ids=getvals(tree, 'ctl00$ctl00$DefaultContent$DefaultContent$Locations$referenceDataCombobox_Locations')
- with open('loc_ids.lst','w') as fo:
- for i in loc_ids:
- fo.write(i+'\t'+loc_ids[i]+'\n')
- exit()
- d=init(tree)
- d.update({
- '__EVENTTARGET': 'ctl00$ctl00$DefaultContent$DefaultContent$Locations$referenceDataCombobox_Locations',
- 'ctl00_ctl00_DefaultContent_DefaultContent_Locations_referenceDataCombobox_Locations_ClientState': '{"value":"'+loc_ids[location]+'"}'
- })
- r=s.post(url, data=d)
- tree=etree.fromstring(r.text)
- # data=init(tree)
- data=init_re(r.text)
- data.update(buying_data)
- r=s.post(url, data=data)
- timestamp_l=datetime.now()
- getexams_text=r.text
- tree=etree.fromstring(getexams_text)
- data=init(tree)
- data.update({
- '__EVENTARGUMENT': '',
- '__EVENTTARGET': 'ctl00$ctl00$DefaultContent$DefaultContent$BuyCapacity',
- 'ctl00$ctl00$MasterScriptManager': 'ctl00$ctl00$MasterScriptManager|ctl00$ctl00$DefaultContent$DefaultContent$BuyCapacity',
- })
- rows=examrows_xpath(tree)
- if not len(rows):
- print('No exams found. Listing time: {}'.format(timestamp_l-timestamp_s), file=f)
- open('getexams'+postfix+'.html','w').write(getexams_text)
- exit()
- for i in rows:
- inp=i[0] # input field, first child of i
- name=inp.attrib['name']
- id=name.split('$')[5] # ctl??
- data[name]=inp.attrib['value']
- cnt=num_xpath(i)[0].strip()
- data['ctl00$ctl00$DefaultContent$DefaultContent$CapacityDataList${}$CapacityEditor$NumberToBuy'.format(id)]=cnt
- data['ctl00_ctl00_DefaultContent_DefaultContent_CapacityDataList_{}_CapacityEditor_NumberToBuy_ClientState'.format(id)]='{{"valueAsString":"{}"}}'.format(cnt)
- # for i in data:
- # if i in ('__EVENTVALIDATION', '__VIEWSTATE'): continue
- # print(i, '--', data[i])
- r=s.post(url, data=data)
- timestamp_f=datetime.now()
- print('Get exams page size:',len(getexams_text), file=f)
- print('Buy exams page size:',len(r.text), file=f)
- open('getexams'+postfix+'.html','w').write(getexams_text)
- open('buyexams'+postfix+'.html','w').write(r.text)
- print('Listing time: {}, Buying time: {}'.format(timestamp_l-timestamp_s, timestamp_f-timestamp_l), file=f)
- f.close()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement