python 结合selenium+PhantomJS爬取王者荣耀官网游戏壁纸

作为一个爬虫小白,学完了爬取静态网页的基本思路和相关库,于是便开始着手学习如何爬取动态页面。
动态网页的定义,在这里就不详细解释了,有疑问的可以自行百度。
首先,爬取动态页面,一般有两种方法:
1. 有的网页向服务器发出请求,会返回json格式的数据,这个数据里就包含着你要爬取的内容,你只要拿到这个json数据,进行相关处理就行。
2. 有的网页想直接拿到这个json数据,却不是那么容易,于是只好采取selenium+PhantomJS的思路。

准备工作

首先,我们来看一下,王者荣耀官网的源码,官网(pvp.qq.com/web201605/wallpaper.shtml ),我用的是火狐浏览器,点击右键查看网页源代码,按Ctrl+F搜索“仲夏夜之梦”,发现没有结果,明明在网页上有的内容,却在源码里找不到,这说明这个网页就是一个动态的页面,有些人也许会疑惑,为什么按F12,却可以找到呢?这是因为,F12所呈现出来的是已经将数据渲染好的页面。
使用selenium+PhantomJS的基本思路就是既然requests库拿到的只是没有内容的框架,那我就模拟浏览器的行为,这样所拿到的页面就是已经将数据渲染完成的页面了。然后用BeautifulSoup库对拿到的页面代码进行处理就行。
大概原理懂了之后,就可以开始爬取了,首先你要安装selenium和PhantomJS,我的python版本是3.x(具体多少忘了),直接打开命令行,pip install selenium就行,至于PhantomJS,可能要花点功夫,网上都有教程,直接百度就好,PhantomJS是一个无头浏览器,没有UI界面,所以我推荐可以再下一个火狐驱动,这样你可以看到页面的跳转等具体是一个什么样子,Firefox的驱动geckodriver 下载地址:github.com/mozilla/geckodriver/releases/ ,详细步骤网上可以搜索教程。

具体操作

现在已经默认大家安装好所需的工具,接下来就可以开始爬取了。为了更好地感受什么叫模拟浏览器的行为(其实就是模拟人的点击,下拉等行为),我们从pvp.qq.com/ 这个页面开始。

from selenium import webdriver

driver = webdriver.PhantomJS()
url = 'http://pvp.qq.com/'
driver.get(url)
print(driver.page_source)
driver.close()

这就是最基本的selenium+PhantomJS语法了,我用的直接是IDLE,注意按F5运行时,弹出的小黑框,千万不要关闭,不想看它的话直接最小化,否则就会报错(不要问我是怎么知道的,我猜是不是相当于直接关闭了浏览器。上述代码实现了获取对应url的内容,并将页面代码输出,很直观易懂,如果不是动态页面,直接用requests库也可以了,但是它的强大就在于模拟人的行为。
还是这个网页,接下来我们要跳转到游戏壁纸的界面。

1.png

将鼠标移到游戏资料tab,然后点击游戏壁纸,就会跳到壁纸页面,接下来就要用selenium模拟行为了。代码如下

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains

driver = webdriver.PhantomJS()
url = 'http://pvp.qq.com/'
driver.get(url)
#1,找到游戏资料这个元素,xpath语法进行元素定位
moveElement = driver.find_element_by_xpath('//a[@title="游戏资料"]')
#2.模拟鼠标悬浮的行为,鼠标事件
ActionChains(driver).move_to_element(moveElement).perform()
#3.点击游戏壁纸这个链接
driver.find_element_by_xpath('//a[@title="游戏壁纸"]').click()
print(driver.page_source)

代码中给出了每一步的解释,注意1,2步是不能省略的,否则会报“定位不到游戏壁纸这个元素”(可以试一下),很好理解,模拟人的行为嘛,如果你的鼠标不移上去,肉眼也看不到“游戏壁纸”这个元素啊。
如果细说selenium的鼠标事件元素定位(很重要),又要占很大的篇幅,这篇文章旨在给读者一个大的轮廓和指引,个中细节还需要自己去查阅资料。
如果电脑有火狐浏览器以及安装好火狐驱动的读者,强烈建议将

driver = webdriver.PhantomJS()

改成

driver = webdriver.Firefox()

运行一下,相信你会更加理解什么叫模拟人的行为,但细心的读者会发现,此时输出的网页源码仍然是前一个网页的代码而不是当前壁纸页面的,明明浏览器已经跳转到壁纸页面,为什么却不是当前源码,老实说,我也不清楚,但我知道解决方法(手动斜眼笑
这里又要说一个概念了,那就是句柄(请自行百度),这里放上代码试验一下

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains

driver = webdriver.PhantomJS()
url = 'http://pvp.qq.com/'
driver.get(url)
#输出当前句柄
print(driver.current_window_handle)
moveElement = driver.find_element_by_xpath('//a[@title="游戏资料"]')
ActionChains(driver).move_to_element(moveElement).perform()
driver.find_element_by_xpath('//a[@title="游戏壁纸"]').click()
#已经跳转页面了,输出当前句柄
print(driver.current_window_handle)
#输出所有句柄
print(driver.window_handles)

运行结果如下

2.png

可以发现,虽然跳转页面了,但是当前句柄却没有发生变化,什么原因我也不知道,如果有大神知道请告诉我(PS.这里我又是使用PhantomJS(),如果使用Firefox()可能不会出现上述结果)
接下来只要

all_h = driver.window_handles
driver.switch_to.window(all_h[1])
print(driver.page_source)

手动转到第二个句柄,输出源码

3.png

已经拿到壁纸页面的源码了(有可能只运行一次拿不到,我也不知道为什么,有可能是服务器的问题?)
接下来只要用BeautifulSoup库对爬到的页面进行解析处理就行了,这里也就不详细展开了。
直接将代码粘贴如下:

import os
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from bs4 import BeautifulSoup
import requests
import time

driver = webdriver.PhantomJS()
driver.maximize_window()
url = 'http://pvp.qq.com/'
driver.get(url)
moveElement = driver.find_element_by_xpath('//a[@title="游戏资料"]')
ActionChains(driver).move_to_element(moveElement).perform()
driver.find_element_by_xpath('//a[@title="游戏壁纸"]').click()

all_h = driver.window_handles
driver.switch_to.window(all_h[1])

time.sleep(3)

os.chdir("D://王者荣耀")
page_num = 0
while page_num < 12:
    soup = BeautifulSoup(driver.page_source, 'html.parser')

    Lists = soup.find_all('div', {'class': 'p_newhero_item'})
    titleLists = []
    hrefLists = []
    for item in Lists:
        subSoup = BeautifulSoup(str(item), 'html.parser')
        titleList = subSoup.find('h4')
        titleLists.append(titleList.text)
        linkList = subSoup.find('li', {'class': 'sProdImgL6'})
        soup = BeautifulSoup(str(linkList), 'html.parser')
        a = soup.find('a')
        hrefLists.append(a['href'])

    for i in range(len(titleLists)):
        url = hrefLists[i]
        r = requests.get(url).content
        path = titleLists[i] + '.jpg'
        try:
            with open(path, 'wb') as f:
                f.write(r)
                print('保存成功 %s.jpg' % titleLists[i])
        except:
            print('保存失败')
    driver.find_element_by_xpath('//a[@class="downpage"]').click()

    time.sleep(3)
    page_num = page_num + 1

driver.close()

需要注意的是,在爬取下一页壁纸的时候,在点击下一页这个元素后,需要time.sleep(),等加载完全,才能接着爬取,会发现有四张照片会被爬取很多遍,这是网页决定的,可以选择链接去重,因为相同名字的图片会被覆盖,所以这里就没有去管它,但有时链接去重是很重要的,电脑桌面是1920*1080的,所以我爬取了对应的图片链接
放上运行结果

4.png

需要事先在D盘建一个“王者荣耀”的文件夹

5.png

综上,便是爬取王者荣耀游戏壁纸的步骤了,没有对代码进行整合重构,第一次记录,可能该详细的地方没有详细,该简略的地方却很啰嗦,请包涵,感谢看到最后。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,165评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,503评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,295评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,589评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,439评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,342评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,749评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,397评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,700评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,740评论 2 313
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,523评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,364评论 3 314
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,755评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,024评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,297评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,721评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,918评论 2 336

推荐阅读更多精彩内容