2017-09-26 21 views
1

나는 거미가 일부 데이터를 pdf 파일과 함께 긁어 모으는데 사용합니다. pdf를 제외한 모든 작업이 완료됩니다. pdf가 file_urls 필드에 다운로드 할 직접 src는 없습니다. HTML이버튼을 누르는 것으로 튀김을 사용하여 파일 다운로드

<a onclick="document.forms[0].target ='_blank';" id="main_0_body_0_lnkDownloadBio" href="javascript:__doPostBack('main_0$body_0$lnkDownloadBio','')">Download full <span class="no-wrap">bio <i class="fa fa-angle-right" data-nowrap-cta=""></i></span></a> 

처럼 보이는 그것은 몇 가지 자바 스크립트 클릭 방식 대신 SRC의 노력 보인다. 이 버튼을 클릭하면 다운로드 할 수있는 새 창이 열립니다. 이제 루아 스크립트와 함께 스플래시 요청을 사용할 계획이었습니다. 코드는 다음과 같습니다

class DataSpider(scrapy.Spider): 

name = config.NAME 
allowed_domains = [config.DOMAIN] 

def start_requests(self): 

    for url in config.START_URLS: 
     yield scrapy.Request(url, self.parse_data) 

def parse_data(self, response): 
    script = """ 
    function main(splash) 
     local url = splash.args.url 
     assert(splash:go(url)) 
     assert(splash:wait(1)) 

     -- go back 1 month in time and wait a little (1 second) 
     assert(splash:runjs("document.getElementById('DownloadBio').click()")) 
     assert(splash:wait(1)) 

     -- return result as a JSON object 
     return { 
      html = splash:html(), 
     } 
    end 
    """ 

    response = json.loads(response.text) 
    res = response['people'] 
    for index, i in enumerate(res[1]): 
     first_name = res[index]['name'] 
     last_name = res[index]['lastname'] 
     location = res[index]['location'] 
     link = res[index]['pageurl'] 
     link = config.HOST + link 
     item = ProtoscraperItem(first_name=first_name, last_name=last_name, title=title, location=location, link=link) 

     # This request is for the detail page and there is more info and pdf. 

     request = SplashRequest(link, self.parse_details, meta={ 
      'splash': { 
       'args': {'lua_source': script, 'wait': 30, 'timeout': 40}, 
       'endpoint': 'execute', 
      },) 
     request.meta['item'] = item 
     request.meta['link'] = link 
     yield request 

def parse_details(self, response): 

    # what to do here 

여기에서 javscript를 실행하려면 앵커 태그를 클릭합니다. 그리고 나는 그것이 작동하고 있다고 생각하지만 다운로드되는 것은 아무것도 없다. 내가 여기서 누락 된 것. 다운로드 할 경로를 지정할 수 있습니까? 나는 이것이 셀레늄으로 가능하다고 생각하지만 어떻게 스플래쉬와 루아로 이것을 할 수 있을까?

+0

'parse_details' 메소드의'response.body'에 무엇이 있습니까? –

+0

방금 ​​PDF 다운로드로 다른 사이트를 확인한 결과 스플래시가 작동하지 않는 것으로 보입니다. 그래서 당신이해야 할 일은 폼이 일반 브라우저에서 제출되고 요청을 직접 시뮬레이트하려고 시도 할 때 어떤 종류의 요청이 시작되는지를 보는 것입니다. –

+0

@ TarunLalwani 일반 브라우저를 통해 폼 요청을 시작하고 pdf로 새 탭을 엽니 다. . 다운로드하거나 문서를 인쇄하기 전에 브라우저 미리보기입니다. 코드에서 동일한 양식을 제출했지만 응답 텍스트와 동일한 HTML이 표시됩니다. 어떻게이 요청을 처리하고 처리 할 수 ​​있습니까? –

답변

1

클릭 단추를 보면 ASP.net에서 "__doPostBack"함수가 호출된다고 생각합니다. 해당 제출 단추를 클릭하면 양식 [0]이 특정 값과 함께 제출됩니다. 양식 제출과 함께 제출되는 모든 요소에 대한 페이지를 고려해야합니다. 이 일을 위해 필요한

인수는

__EVENTTARGET,

__EVENTARGUMENT

__VIEWSTATE

__VIEWSTATEGENERATOR

__EVENTVALIDATION

012입니다

어쩌면이 인수는 일반적으로 양식의 숨겨진 값으로 설정됩니다. (귀하의 웹 페이지에서 확인하십시오.)

arguments = {'__EVENTTARGET': 'main_0$body_0$lnkDownloadBio', 
       '__EVENTARGUMENT': '', 
       '__VIEWSTATE': viewstate, 
       '__VIEWSTATEGENERATOR': viewstategen, 
       '__EVENTVALIDATION': eventvalid, 
       'search': '', 
       'filters': '', 
       'score': '' 
       } 

    HEADERS = { 
       'Content-Type':'application/x-www-form-urlencoded', 
       'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) 
       AppleWebKit/537.36 (KHTML, like Gecko) 
       Chrome/60.0.3112.101 Safari/537.36', 
       'Accept': 'text/html, application/xhtml + xml, 
       application/xml;q = 0.9, image/webp, image/apng, * 
       /*;q = 0.8' 
       } 

    data = urllib.urlencode(arguments) 
    r = requests.post(submitin_url, data, allow_redirects=False, headers=HEADERS) 

    with open(some_filename, 'wb') as f: 
     f.write(r.content) 

나는 내 프로젝트와 비슷한 종류의 작업을했으며 이와 같은 작업을 수행했습니다. 파이썬 요청을 사용하여 양식 값과 인수를 보냅니다. 응답은 다운로드하려는 파일입니다. 파일에 기록하고 확장자가 올바른지 확인하십시오. 나는 그것이 당신에게 도움이되기를 바랍니다.