我正在尝试在脚本中访问NCBI图像搜索页面(http://www.ncbi.nlm.nih.gov/images)上的搜索结果。我想提供一个搜索字词,报告所有结果,然后转到下一个搜索字词。为此,我需要在第一页之后到达结果页面,所以我正在尝试使用python mechanize来实现它:
import mechanize
browser=mechanize.Browser()
page1=browser.open('http://www.ncbi.nlm.nih.gov/images?term=drug')
a=browser.links(text_regex='Next')
nextlink=a.next()
page2=browser.follow_link(nextlink)
这只是让我回到搜索结果的第一页(在变量page2中)。我做错了什么,我怎样才能进入第二页以及更远的地方?
答案 0 :(得分:6)
不幸的是,该页面使用Javascript将2459字节的表单变量POST到服务器,只是为了导航到后续页面。以下是一些变量(我总计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
等文件。
注意:在使用之前,您需要将POSTDATA
替换为contents of this paste blob(它会在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())