通过各种了解,这种异步刷新的网页似乎只能用浏览器加上模拟操作来实现刷新。因为JS需要一个浏览器内核来解析。所以Python + PhantomJS + Selenium看样子是不错的做法。这里PhantomJS号称无头(Headless)浏览器。顾名思义,就是不需要Header啦。于是很快找到样例,对代码修改之。
from bs4 import BeautifulSoup from selenium import webdriver import time class ImgCrawler: def __init__(self,searchlink = None): self.link = searchlink self.soupheader = {'User-Agent':"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.134 Safari/537.36"}#BeautifulSoup用的头 self.scrolldown = None self.jsdriver = None def getPhantomJSDriver(self): self.jsdriver = webdriver.PhantomJS() self.jsdriver.get(self.link) def scrollDownUsePhatomJS(self, scrolltimes = 1, sleeptime = 10): for i in range(scrolltimes): print u"开始执行第" + str(i+1) + u'次下拉操作' self.jsdriver.execute_script('window.scrollTo(0,document.body.scrollHeight);')#执行JavaScript实现网页下拉到底部 print(u'第' + str(i+1) + u'次下拉操作执行完成,等待网页加载') time.sleep(sleeptime) # 获取html结构 def getSoup(self, parser=None): print 'a', self.jsdriver.page_source return BeautifulSoup(self.jsdriver.page_source, parser) def getActualUrl(self, soup=None, flag=None, classflag=None, jsonflaglink=None, jsonflagtype=None): actualurl = [] for a in soup.find_all(flag, {"class": classflag}): link = json.loads(a.text)[jsonflaglink] filetype = json.loads(a.text)[jsonflagtype] detailurl = link + u'.' + filetype actualurl.append(detailurl) return actualurl if __name__ == '__main__': search_url = "https://www.google.com.hk/search?safe=strict&hl=zh-CN&site=imghp&tbm=isch&source=hp&biw=&bih=&btnG=Google+%E6%90%9C%E7%B4%A2&q=" #从google搜索时提取出来的链接,不同google站点不同 queryword = raw_input(u'搜索关键词=')#输入关键词 #去掉空格 query = queryword.split() query = '+'.join(query) # weblink = search_url + query weblink = "https://www.google.com.hk/search?as_st=y&tbm=isch&hl=zh-CN&as_q=" + query + "&as_epq=&as_oq=&as_eq=&imgsz=&imgar=&imgc=&imgcolor=&imgtype=&cr=&as_sitesearch=&safe=images&as_filetype=&as_rights=" #生成对象 img = ImgCrawler(weblink) #模拟浏览器获取链接 img.getPhantomJSDriver() #模拟下拉刷新操作 img.scrollDownUsePhatomJS(2,5) #获取html框架 soup = img.getSoup('html.parser') print weblink print soup #获取网页链接 actualurllist = img.getActualUrl(soup,'div','rg_meta','ou','ity') print len(actualurllist)
运行一下,Len为0。不好用啊。
回头想想,基本上谈到用PhantomJS的文章,要么年代久远,3年以上,要么就是搜其他的网站的,很少提及谷歌的。会不会这里有问题。
打印BeautifulSoup获取的网页,发现和直接用头申请来的完全不一样啊,只有谷歌自己生成的缩略图,而且网页Html代码,除了框架和修饰的部分,核心内容都不太一样(虽然搜到的结果是一样的)。估计谷歌针对各种浏览器进行了区别对待——也可以说是自适应匹配吧,毕竟把浏览器窗口最大化标准化网页布局都有变化。PhantomJS估计没有更新,就给了个最古老的页面,由于长期不更新,已经更不上时代了。
这个贪图便宜简单做的修改应该不行,需要进一步研究。