Ecco cosa sto cercando di fare: andare here, quindi premere "cerca". Prendi i dati, poi fai clic su "Avanti" e continua a colpire fino a quando non sei fuori dalle pagine. Tutto fino a colpire "next" funziona. Ecco il mio codice. Il formato di r.content è radicalmente diverso le due volte che lo stampo, indicando che qualcosa di diverso sta accadendo tra le richieste GET e POST anche se voglio un comportamento molto simile. Perché questo potrebbe accadere?Effettuare la successiva richiesta POST in sessione non funziona - scraping web
Quello che trovo strano è che, anche dopo la richiesta POST che sembra restituire le cose sbagliate, posso ancora analizzare gli urls di cui ho bisogno, solo il campo di input __EVENTVALIDATION.
Il messaggio di errore (fine del codice) indica che il contenuto non include questi dati che ho bisogno di fare una richiesta successiva, ma la navigazione verso la pagina mostra che ha quei dati e che il formato è molto simile alla prima pagina.
EDIT: lo sto facendo aprire pagine Web in base all'HTML che sta analizzando e qualcosa non è assolutamente corretto. l'esecuzione del codice seguente aprirà quelle pagine.
La farmi ottiene un sito web con i dati in questo modo:
<input type="hidden" name="__VIEWSTATEGENERATOR" id="__VIEWSTATEGENERATOR" value="4424DBE6">
<input type="hidden" name="__VIEWSTATEENCRYPTED" id="__VIEWSTATEENCRYPTED" value="">
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="TlIgNH
Mentre il POST produce un sito con tutti i dati nella parte inferiore della pagina in chiaro, in questo modo:
|0|hiddenField|__EVENTTARGET||0|hiddenField|__EVENTARGUMENT||0|hiddenField|_
import requests
from lxml import html
from bs4 import BeautifulSoup
page = requests.get('http://search.cpsa.ca/physiciansearch')
print('got page!')
d = {"ctl00$ctl13": "ctl00$ctl13|ctl00$MainContent$physicianSearchView$btnSearch",
"ctl00$MainContent$physicianSearchView$txtLastName": "",
'ctl00$MainContent$physicianSearchView$txtFirstName': "",
'ctl00$MainContent$physicianSearchView$txtCity': "",
"__VIEWSTATEENCRYPTED":"",
'ctl00$MainContent$physicianSearchView$txtPostalCode': "",
'ctl00$MainContent$physicianSearchView$rblPractice': "",
'ctl00$MainContent$physicianSearchView$ddDiscipline': "",
'ctl00$MainContent$physicianSearchView$rblGender': "",
'ctl00$MainContent$physicianSearchView$txtPracticeInterests': "",
'ctl00$MainContent$physicianSearchView$ddApprovals': "",
'ctl00$MainContent$physicianSearchView$ddLanguage': "",
"__EVENTTARGET": "ctl00$MainContent$physicianSearchView$btnSearch",
"__EVENTARGUMENT": "",
'ctl00$MainContent$physicianSearchView$hfPrefetchUrl': "http://service.cpsa.ca/OnlineService/OnlineService.svc/Services/GetAlbertaCities?name=",
'ctl00$MainContent$physicianSearchView$hfRemoveUrl': "http://service.cpsa.ca/OnlineService/OnlineService.svc/Services/GetAlbertaCities?name=%QUERY",
'__ASYNCPOST': 'true'}
h ={ "X-MicrosoftAjax":"Delta = true",
"X-Requested-With":"XMLHttpRequest",
"User-Agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36"
}
urls = []
with requests.session() as s:
r = s.get("http://search.cpsa.ca/PhysicianSearch",headers=h)
soup = BeautifulSoup(r.content, "lxml")
tree = html.fromstring(r.content)
html.open_in_browser(tree)
ev = soup.select("#__EVENTVALIDATION")[0]["value"]
vs = soup.select("#__VIEWSTATE")[0]["value"]
vsg = soup.select("#__VIEWSTATEGENERATOR")[0]["value"]
d["__EVENTVALIDATION"] = ev
d["__VIEWSTATEGENERATOR"] = vsg
d["__VIEWSTATE"] = vs
r = s.post('http://search.cpsa.ca/PhysicianSearch', data=d,headers=h)
print('opening in browser')
retrievedUrls = tree.xpath('//*[@id="MainContent_physicianSearchView_gvResults"]/tr/td[2]/a/@href')
print(retrievedUrls)
for url in retrievedUrls:
urls.append(url)
endSearch = False
while endSearch == False:
tree = html.fromstring(r.content)
html.open_in_browser(tree)
soup = BeautifulSoup(r.content, "lxml")
print('soup2:')
## BREAKS HERE
ev = soup.select("#__EVENTVALIDATION")[0]["value"]
## BREAKS HERE,
vs = soup.select("#__VIEWSTATE")[0]["value"]
vsg = soup.select("#__VIEWSTATEGENERATOR")[0]["value"]
d["ctl00$ctl13"] = "ctl00$MainContent$physicianSearchView$ResultsPanel|ctl00$MainContent$physicianSearchView$gvResults$ctl01$btnNextPage"
d["__EVENTVALIDATION"] = ev
d["__EVENTTARGET"] = ""
d["__VIEWSTATEGENERATOR"] = vsg
d["__VIEWSTATE"] = vs
d["ctl00$MainContent$physicianSearchView$gvResults$ctl01$ddlPager"] = 1
d["ctl00$MainContent$physicianSearchView$gvResults$ctl01$ddlPager"] = 1
d["ctl00$MainContent$physicianSearchView$gvResults$ctl01$btnNextPage"] = "Next"
r = requests.post('http://search.cpsa.ca/PhysicianSearch', data=d,headers=h)
tree = html.fromstring(r.content)
tree = html.fromstring(r.content)
retrievedUrls = tree.xpath('//*[@id="MainContent_physicianSearchView_gvResults"]/tr/td[2]/a/@href')
print(urls)
print(retrievedUrls)
endSearch = True
...
Traceback (most recent call last):
File "C:\Users\daniel.bak\workspace\Alberta Physician Scraper\main\main.py", line 63, in <module>
ev = soup.select("#__EVENTVALIDATION")[0]["value"]
IndexError: list index out of range
Questo programma ha spinta mentale , Quindi -1 –
@BhargavRao, lol sarebbe peggio se mi picchiava;) –
Stavo anche diventando pazzo. Grazie mille per l'aiuto, verificando ora che funzioni. In realtà ho trovato una soluzione alternativa un minuto prima che tu lo scoprissi, lol. –