2017-12-31 214 views
0

파이어 폭스 브라우저를 사용하여 다운로드 사이트에 로그인하고 쿼리 단추 중 하나를 클릭하십시오. "opening report1.csv"라는 작은 창이 나타나고 '파일 열기'또는 '파일 저장'을 선택할 수 있습니다. 파일을 저장합니다. 이 작업 Live HTTP headers를 들어 "Content-Disposition : attachment;"가있는 웹 페이지를 가져올 수 없습니다. 파이썬 요청 사용하기

나를 보여줍니다

은 https : // myserver를/ReportPage & NAME를 다운로드 = ALL & DATE = THISYEAR

GET/ReportPage & NAME를 다운로드 = ALL & DATE = THISYEAR HTTP/1.1
호스트 : MYSERVER
사용자 에이전트 : 모질라/5.0 (X11, 리눅스 x86_64의 장, : 52.0) 게코/20100101 파이어 폭스/52.0
응용 프로그램/xml, q = 0.9, /, q = 0.8
수락 언어 : en-US, en; q = 0.8, de-DE; q = ? 0.5, 드, Q = 0.3
수락 - 인코딩 : gzip으로는, 폐, BR
리퍼러 : https : //로 MYSERVER/ReportPage 4 & NAME = ALL & DATE = THISYEAR
쿠키 : JSESSIONID = 88DEDBC6880571FDB0E6E4112D71B7D6
연결 : 연결 유지
업그레이드 - 안전하지 않은 요청 : 1

HTTP/1.1 200 OK
,451,515,날짜 : 2017년 (토) 년 12 월 30 일 그리니치 표준시 22시 37분 40초
서버 : 아파치 - 코요테/1.1
마지막 수정 : 2017년 12월 30일 (토)
이 만료 그리니치 표준시 22시 37분 40초 : 1970년 (목) 00 01 일월 00 : 00 GMT
Pragma : no-cache
캐시 제어 : no-cache, no-store
Content-Disposition : attachment; filename = "report1.csv"; 파일 이름 * = UTF-8''report1.csv
콘텐츠 유형 : 텍스트/CSV
콘텐츠 길이 : 332,369
연결 유지 : 제한 시간 = 5, 최대 = 100
연결 : 연결 유지

이제 요청을 통해이를 에뮬레이션하려고합니다.

$ python3 
>>> import requests 
>>> from lxml import html 
>>> 
>>> s = requests.Session() 
>>> s.verify = './myserver.crt' # certificate of myserver for https 
>>> 
>>> # get the login web page to enter username and password 
... r = s.get('https://myserver') 
>>> 
>>> # Get url for logging in. It's the action-attribute in the form anywhere. 
... # We use xpath. 
... tree = html.fromstring(r.text) 
>>> loginUrl = 'https://myserver/' + list(tree.xpath("//form[@id='id4']/@action"))[0] 
>>> print(loginUrl) # it contains a session-id 
https://myserver/./;jsessionid=77EA70CB95252426439097E274286966?0-1.loginForm 
>>> 
>>> # logging in with username and password 
... r = s.post(loginUrl, data = {'username':'ingo','password':'mypassword'}) 
>>> print(r.status_code) 
200 
>>> # try to get the download file using url from Live HTTP headers 
... downloadQueryUrl = 'https://myserver/ReportPage?download&NAME=ALL&DATE=THISYEAR' 
>>> r = s.get(downloadQueryUrl) 
>>> print(r.status_code) 
200 
>>> print(r. headers) 
{'Connection': 'Keep-Alive', 
'Date': 'Sun, 31 Dec 2017 14:46:03 GMT', 
'Cache-Control': 'no-cache, no-store', 
'Keep-Alive': 'timeout=5, max=94', 
'Transfer-Encoding': 'chunked', 
'Expires': 'Thu, 01 Jan 1970 00:00:00 GMT', 
'Pragma': 'no-cache', 
'Content-Encoding': 'gzip', 
'Content-Type': 'text/html;charset=UTF-8', 
'Server': 'Apache-Coyote/1.1', 
'Vary': 'Accept-Encoding'} 
>>> print(r.url) 
https://myserver/ReportPage?4&NAME=ALL&DATE=THISYEAR 
>>> 

요청이 성공했지만 파일 다운로드 페이지가 표시되지 않습니다. "Content-Disposition : attachment;"가 없습니다. 헤더의 항목. 쿼리가 시작되는 페이지 만 가져옵니다 (예 : referer의 페이지.

세션 쿠키와 관련이 있습니까? 요청이 자동으로이를 관리하는 것 같습니다. csv 파일을위한 특별한 처리가 있습니까? 스트림을 사용해야합니까? 라이브 HTTP 헤더로 표시된 다운로드 URL이 올바른 것입니까? 어쩌면 역동적 인 창조가 있을까요?

"Content-Disposition : attachment;"라는 웹 페이지를 어떻게 얻을 수 있습니까? myserver에서 요청 파일을 다운로드 하시겠습니까?

+0

어쩌면 요청할 헤더를 추가 할 필요가 없습니다. "User-Agent" – furas

+0

'r.text'를 확인 했습니까? 어쩌면 유용한 정보가있을 수 있습니다. 경고 메시지가 될 수 있습니다. 파일로 작성하고 브라우저에서이 파일을 열 수 있습니다. – furas

+0

@furas 이것을 가리켜 주셔서 감사합니다. 나는 이것을 시험해 볼 것이다. – Ingo

답변

0

알겠습니다. @Patrick Mevzek은 올바른 방향을 알려줍니다. 감사합니다.

로그인 한 후 첫 번째 로그인 페이지에 머무르지 않고 쿼리를 호출합니다. 대신 보고서 페이지를 요청하고 query-url을 추출한 다음 query-url을 요청합니다. 이제 헤더에 "Content-Disposition : attachment;"라는 응답이 표시됩니다. 이제 텍스트를 표준 출력으로 간단하게 출력 할 수 있습니다. 출력을 모든 파일로 리디렉션 할 수 있기 때문에 선호합니다. Info-messages는 stderr로 넘어가므로 리다이렉트 된 출력을 엉망으로 만들지 않습니다. 대표 전화는 ./download >out.csv입니다.

스크립트 템플리트의 완전성을 위해 스크립트 템플리트의 작동을 명확히하기 위해 오류 검사를하지 않습니다.

#!/usr/bin/python3 

import requests 
import sys 
from lxml import html 

s = requests.Session() 
s.verify = './myserver.crt' # certificate of myserver for https 

# get the login web site to enter username and password 
r = s.get('https://myserver') 

# Get url for logging in. It's the action-attribute in the form anywhere. 
# We use xpath. 
tree = html.fromstring(r.text) 
loginUrl = 'https://myserver/' + tree.xpath("//form[@id='id4']/@action")[0] 

# logging in with username and password and go to ReportPage with queries 
r = s.post(loginUrl, data = {'username':'ingo','password':'mypassword'}) 
queryUrl = 'https://myserver/ReportPage?NAME=ALL&DATE=THISYEAR' 
r = s.get(queryUrl) 

# Get the download link for this query from this site. It's a link anywhere 
# with value 'Download (UTF8)' 
tree = html.fromstring(r.text) 
downloadUrl = 'https://myserver/' + tree.xpath("//a[.='Download (UTF8)']/@href")[0] 

# get the download file 
r = s.get(downloadUrl) 
if r.headers.get('Content-Disposition'): 
    print('Downloading ...', file=sys.stderr) 
    print(r.text) 

# log out 
r = s.get('https://myserver/logout')