不幸的是,頁面使用Javascript將2459字節的表單變量發送到服務器,只是導航到後續頁面。這裏有幾個變量(我算上共有38個瓦爾):
EntrezSystem2.PEntrez.ImagesDb.Images_SearchBar.Term=drug
EntrezSystem2.PEntrez.ImagesDb.Images_SearchBar.CurrDb=images
EntrezSystem2.PEntrez.ImagesDb.Images_ResultsPanel.Entrez_Pager.CurrPage=2
你需要構建一個POST請求,其中包含一些或所有這些變量的服務器。幸運的是,如果你在頁面2上工作,你可以簡單地增加CurrPage
併發送另一個POST來獲得每個後續頁面的結果(不需要提取鏈接)。
更新 - 該網站是一個完全痛苦的屁股,但這裏是一個基於POST的2-N頁面的刮擦。將MAX_PAGE
設置爲最高頁碼+1。該腳本將生成像file_000003.html
這樣的文件。
注意:在你使用它,你需要與contents of this paste blob更換POSTDATA
(其1個月到期)。這僅僅是一個由Firebug捕獲的POST請求,我用它來種子正確的參數:
import cookielib
import json
import mechanize
import sys
import urllib
import urlparse
MAX_PAGE = 6
TERM = 'drug'
DEBUG = False
base_url = 'http://www.ncbi.nlm.nih.gov/images?term=' + TERM
browser = mechanize.Browser()
browser.set_handle_robots(False)
browser.set_handle_referer(True)
browser.set_debug_http(DEBUG)
browser.set_debug_responses(DEBUG)
cjar = cookielib.CookieJar()
browser.set_cookiejar(cjar)
# make first GET request. this will populate the cookie
res = browser.open(base_url)
def write(num, data):
with open('file_%06d.html' % num, 'wb') as out:
out.write(data)
def encode(kvs):
res = []
for key, vals in kvs.iteritems():
if isinstance(vals, list):
for v in vals:
res.append('%s=%s' % (key, urllib.quote(v)))
else:
res.append('%s=%s' % (key, urllib.quote(vals)))
return '&'.join(res)
write(1, res.read())
# set this var equal to the contents of this: http://pastebin.com/UfejW3G0
POSTDATA = '''<post data>'''
# parse the embedded json vars into POST parameters
PREFIX1 = 'EntrezSystem2.PEntrez.ImagesDb.'
PREFIX2 = 'EntrezSystem2.PEntrez.DbConnector.'
params = dict((k, v[0]) for k, v in urlparse.parse_qs(POSTDATA).iteritems())
base_url = 'http://www.ncbi.nlm.nih.gov/images'
for page in range(2, MAX_PAGE):
params[PREFIX1 + 'Images_ResultsPanel.Entrez_Pager.CurrPage'] = str(page)
params[PREFIX1 + 'Images_ResultsPanel.Entrez_Pager.cPage'] = [str(page-1)]*2
data = encode(params)
req = mechanize.Request(base_url, data)
cjar.add_cookie_header(req)
req.add_header('Content-Type', 'application/x-www-form-urlencoded')
req.add_header('Referer', base_url)
res = browser.open(req)
write(page, res.read())
感謝您的幫助。我不知道任何Javascript,所以我可以使用機械化提供的一些POST功能,或者我需要在Javascript中做些什麼嗎? – andy 2011-05-02 16:47:50
順便說一句,我曾嘗試以前使用wget和捲曲與這些變量的POST數據,並得到基本相同的行爲:總是隻是得到結果的第一頁,無論我通過什麼CurrPage號碼。這很令人困惑。 – andy 2011-05-02 16:49:20
您可以從機械化提交POST。你試圖抓取的網站正在做一些瘋狂的事情,所以它可能有點涉及到確切需要提交哪些變量。我會用一個機械化POST的例子來更新我的答案,以防萬一。 – samplebias 2011-05-03 20:10:05