赞
踩
"静态网页":一次性加载,爬虫可以爬到全部信息。关于静态网页的Demo
“动态网页”:分多次加载,爬虫只能爬取部分信息(无法直接执行JavaScript代码带来的问题)。
接下来让我们用selenium开始解析动态网页吧
selenium最初是一个自动化测试工具,而爬虫中使用它主要是为了解决requests无法直接执行JavaScript代码的问题。
selenium本质是通过驱动浏览器,完全模拟浏览器的操作,比如跳转、输入、点击、下拉等,来拿到网页渲染之后的结果,可支持多种浏览器。
提供两种方法
1、pip xxx
2、打开pycharm等软件,自行搜索库名下载。
下方是selenium支持的浏览器
Chrome
Firefox
PhantomJS
Safari
Edge
根据自己的浏览器类别去下载对应的浏览器插件,接下来用Chrome做例子。
1、查看自己浏览器的版本
打开浏览器,在地址栏输入chrome://version/
2.下载对应的插件
Chrome插件下载地址
找到和自己浏览器版本最接近的版本,点击进去,点击对应操作系统的链接进行下载。
from selenium import webdriver
driver = webdriver.Chrome ('你下载的浏览器插件的路径')
如果弹出Chrome窗口,恭喜你。
如果报错,请你检查一下上面步骤或者百度
超级好看的的壁纸网站
简单说一下这个网站的特点
1、下拉式加载壁纸
2、JS加载壁纸
3、每个壁纸都有很多版本(4K、2K等)
import os import random import ssl import time ssl._create_default_https_context = ssl._create_unverified_context from bs4 import BeautifulSoup import urllib.request ''' 在这说明一下 为什么要用selenium 1、有些页面是异步加载返回的,它不是直接返回请求的数据,爬虫只能抓取到最开始的部分数据(空壳数据)后面的数据是由Javascript异步加载进来的 2、爬虫不能解决js加载的问题,所以我们要用selenium 3、我们需要利用selenium抓取js加载的数据(壁纸) ''' from selenium import webdriver # 调用浏览器做操作 from selenium.webdriver.common.by import By # 按照什么方式查找,By.ID,By.CSS_SELECTOR from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.wait import WebDriverWait # 等待页面加载某些元素 js加载 # 指定Chrome驱动的位置 chromePath = '/Users/apple/Downloads/Chrome下载/chromedriver' # 壁纸保存的路径 savePath = '/Users/apple/Downloads/desktopPictureTest' # 下该函数为载壁纸 pageCode参数:选择壁纸的种类 maxSlideNumber参数:下拉的次数 def downloadPicture(pageCode, maxSlideNumber): # 打开Chrome浏览器 browser = webdriver.Chrome(chromePath) print('打开Chrome中...') # 由于这个网站下拉加载更多的壁纸 所以 初始化下拉次数 slideNumber = 1 # 存放爬取到的图片href DownloadList = [] # 下载失败的图片href noDownloadList = [] try: # 跳转到壁纸页面 browser.get('https://ss.netnr.com/wallpaper' + pageCode) # 我们需要的壁纸放在class名为'row'的div中 我们需要等这个div加载好 我们再抓数据 while True: try: # 有时候服务器和网会有点小问题,所以给row10秒加载 如果加载大于10秒 刷新网页 重新开始 wait = WebDriverWait(browser, 10) # 等到CLASS_NAME为raw的div加载完毕,最多等10秒 wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'row'))) # 如果达到了下拉次数,则跳出循环 if slideNumber > maxSlideNumber: break # 没达到下拉次数 +1继续循环 slideNumber = slideNumber + 1 # 如果div加载成功我们需要更多的壁纸,所以下滑到底。 print('下拉中....') browser.execute_script('window.scrollTo(0,document.body.scrollHeight)') # 睡眠5秒再次下拉 可以充分展现下拉的用处 time.sleep(5) # 如果加载大于10秒 刷新网页 重新开始 except: # 刷新网页 print('刷新网页...') browser.refresh() # 此时的网页就是下拉n次后的网页 蕴含着好多壁纸 # 处理网页内容 soup = BeautifulSoup(browser.page_source, "html.parser") # 抓取div rows = soup.findAll(class_='list-group') for i in rows: # 抓取a标签 aHref = i.findAll('a') for i in aHref: # 抓取href(下载地址) src = i.get('href') # 把壁纸的href放入列表 DownloadList.append(src) # 为什么要break呢 因为此网站提供好几个版本的壁纸 我们只需要第一个(画质最好的版本) break # 此时开始下载壁纸 # 如果文件夹不存在则创建 if not os.path.exists(savePath): os.makedirs(savePath) # 所有的图片处理完成(失败或者成功) 才可以结束 # 可能因为网络和机器的问题,下载会失败,所以采用循环机制 print('\033[0;36m') print('共抓取到' + str(DownloadList.__len__()) + '张壁纸') print('\033[0m') print( '<=====================================================================================================================================>') # 无论处理成功还是失败,列表的数据处理完才能结束 while DownloadList.__len__()>0: # 遍历列表 逐个下载壁纸 for i in DownloadList: # 壁纸名称 name = i.split('/')[-1] # 避免名称重复 采用随机数 saveFile = savePath + "/" + 'qianFuXin' + str(random.randint(0, 9)) + str(random.randint(0, 9)) + \ str(random.randint(0, 9)) + str(random.randint(0, 9)) + name if os.path.exists(saveFile): print(saveFile + '已经存在') exit(0) try: urllib.request.urlretrieve(i, saveFile) # 下载成功就移除列表 DownloadList.remove(i) print('处理成功!该文件为:' + saveFile) print('还剩' + str(DownloadList.__len__()) + '张') print( '<=====================================================================================================================================>') except: # 下载失败就等下次继续下载 noDownloadList.append(i) print("\033[37;41m处理失败\033[0m") DownloadList.remove(i) print('还剩' + str(DownloadList.__len__()) + '张') print( '<=====================================================================================================================================>') # 输出未完成的href 人工处理 print("\033[37;41m未完成的图片href如下\033[0m") for i in noDownloadList: print(i) finally: # 关闭Chrome页面 browser.close() def initChoose(): pictureKindAndCode = {'最新壁纸': '#', '4K专区': '#36', '美女模特': '#6', '爱情美图': '#30', '风景大片': '#9', '小清新': '#15', '动漫卡通': '#26', '明星风尚': '#11', '萌宠动物': '#14', '游戏壁纸': '#5', '汽车天下': '#12', '炫酷时尚': '#10', '日历壁纸': '#29', '影视剧照': '#7', '节日美图': '#13', '军事天地': '#22', '劲爆体育': '#16', 'baby秀': '#18', '文字控': '#35'} pictureKindAndNumber = {} number = 1 print( '<=====================================================================================================================================>') for i in pictureKindAndCode: print(str(number) + '、' + i) pictureKindAndNumber[str(number)] = i number = number + 1 print( '<=====================================================================================================================================>') userChoose = input("\033[1;30;47m输入壁纸编号(范围:1-19):\033[0m") # 正则表达式判断输入是不是在数字范围内 # matches 只要有一个满足就行 11 是满足[1-9]的 因为1满足了[1-9] # 做个标记 # 改用isdigit if userChoose.isdigit() and 20 > int(userChoose) > 0: pageCode = pictureKindAndCode[pictureKindAndNumber[userChoose]] else: print("\033[37;41m请输入1-19之间的数字\033[0m") exit(0) maxSlideNumber = input("\033[1;30;47m输入下拉次数(范围1-99):\033[0m") # 正则表达式判断输入是不是在数字范围内 # matches 只要有一个满足就行 if userChoose.isdigit() and 100 > int(userChoose) > 0: pass else: print("\033[37;41m请输入1-99之间的数字\033[0m") exit(0) return pageCode, maxSlideNumber if __name__ == '__main__': print('\033[0;36m') print('Default ChromePath\t==>\t' + chromePath) print('Default SavePicturePath\t==>\t' + savePath) print('\033[0m') # 确定路径是都正确 defaultPathChoose = input('请查看上方路径是否正确,如果正确输入1继续执行程序,否则输入任意字符退出程序:') if defaultPathChoose.__eq__('1'): pass else: exit(0) # 初始化选择 pageCode, maxSlideNumber = initChoose() print('准备下载壁纸.....') # 下载壁纸 downloadPicture(pageCode, int(maxSlideNumber)) #结束下载 print('\033[0;36m') print('下载结束') print('\033[0m')
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。