js抓取网页内容(抓的妹子图都是直接抓Html就可以的 )
优采云 发布时间: 2021-10-07 06:06js抓取网页内容(抓的妹子图都是直接抓Html就可以的
)
介绍
之前拍的姐妹图可以直接用Html抓拍,也就是Chrome的浏览器F12。
Elements 页面结构和 Network 数据包捕获返回相同的结果。以后抓一些
网站(比如煎鸡蛋,还有那种小网站)我发现了。网络抓包
没有获取到数据,但是Elements中出现了情况。原因是:页面的数据是
由 JavaScript 动态生成:
抓不到数据怎么破?一开始想着自己学一波JS基础语法,然后尝试模拟抓包。
拿到别人的js文件,自己分析一下逻辑,然后摆弄真实的URL,然后就是
放弃。毕竟要爬取的页面太多了。每个这样的分析什么时候...
我偶然发现有一个自动化测试框架:Selenium 可以帮助我们处理这个问题。
简单说说这个东西的使用,我们可以写代码让浏览器:
那么这个东西不支持浏览器功能,需要配合第三方浏览器使用,
支持以下浏览器,需要将对应的浏览器驱动下载到Python对应的路径:
铬合金:
火狐:
幻影JS:
IE:
边缘:
歌剧:
下面直接开始本节的内容吧~
1.安装硒
这个很简单,直接通过pip命令行安装:
sudo pip install selenium
PS:记得公司小伙伴问我为什么在win上不能执行pip,我下载了很多pip。
其实安装Python3的话,默认已经自带pip了,需要单独配置环境
变量,pip的路径在Python安装目录的Scripts目录下~
在Path后面加上这个路径就行了~
2.下载浏览器驱动
因为Selenium没有浏览器,需要依赖第三方浏览器,调用第三方
如果你用的是新浏览器,需要下载浏览器的驱动,因为我用的是Chrome,所以我会用
我们以 Chrome 为例。其他浏览器可以自行搜索相关信息!打开 Chrome 浏览器并输入:
chrome://version
可以查看Chrome浏览器版本的相关信息,这里主要注意版本号:
61.好的,那么到下面网站查看对应的驱动版本号:
好的,接下来下载v2.34版本的浏览器驱动:
下载完成后,解压zip文件,将解压后的chromedriver.exe复制到Python
脚本目录。(这里不用担心win32,64位浏览器可以正常使用!)
PS:对于Mac,将解压后的文件复制到usr/local/bin目录下
对于Ubuntu,复制到:usr/bin目录
接下来我们写一个简单的代码来测试一下:
from selenium import webdriver
browser = webdriver.Chrome() # 调用本地的Chrome浏览器
browser.get('http://www.baidu.com') # 请求页面,会打开一个浏览器窗口
html_text = browser.page_source # 获得页面代码
browser.quit() # 关闭浏览器
print(html_text)
执行这段代码会自动调出浏览器访问百度:
并且控制台会输出HTML代码,也就是直接获取到的Elements页面结构,
JS执行后的页面~接下来就可以抢到我们的煎蛋少女图了~
3.Selenium简单实战:抢煎蛋少女图
直接分析Elements页面的结构,找到你想要的关键节点:
明明这是我们抓到的*敏*感*词*姐的照片,复制这个网址看看我们打印出来的
页面结构有没有这个东西:
是的这很好。有了这个页面数据,让我们通过一波美汤来搞定我们
你要的资料~
经过上面的过滤,我们就可以得到我们妹图的URL:
只需打开一个验证,啧:
看到下一页只有30个*敏*感*词*姐,显然满足不了我们。我们第一次加载它。
当你第一次得到一波页码的时候,然后你就知道有多少页了,然后你就可以拼接URL并自己加载了
不同的页面,比如这里总共有448个页面:
可以拼接成这样的网址:
获取过滤下的页码:
接下来,我将填写代码,循环抓取每个页面上的*敏*感*词*姐,并将其下载到本地。
完整代码如下:
import os
from selenium import webdriver
from bs4 import BeautifulSoup
import urllib.request
import ssl
import urllib.error
base_url = 'http://jandan.net/ooxx'
pic_save_path = "output/Picture/JianDan/"
# 下载图片
def download_pic(url):
correct_url = url
if url.startswith('//'):
correct_url = url[2:]
if not url.startswith('http'):
correct_url = 'http://' + correct_url
print(correct_url)
headers = {
'Host': 'wx2.sinaimg.cn',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/61.0.3163.100 Safari/537.36 '
}
try:
req = urllib.request.Request(correct_url, headers=headers)
resp = urllib.request.urlopen(req)
pic = resp.read()
pic_name = correct_url.split("/")[-1]
with open(pic_save_path + pic_name, "wb+") as f:
f.write(pic)
except (OSError, urllib.error.HTTPError, urllib.error.URLError, Exception) as reason:
print(str(reason))
# 打开浏览器模拟请求
def browser_get():
browser = webdriver.Chrome()
browser.get('http://jandan.net/ooxx')
html_text = browser.page_source
page_count = get_page_count(html_text)
# 循环拼接URL访问
for page in range(page_count, 0, -1):
page_url = base_url + '/page-' + str(page)
print('解析:' + page_url)
browser.get(page_url)
html = browser.page_source
get_meizi_url(html)
browser.quit()
# 获取总页码
def get_page_count(html):
soup = BeautifulSoup(html, 'html.parser')
page_count = soup.find('span', attrs={'class': 'current-comment-page'})
return int(page_count.get_text()[1:-1]) - 1
# 获取每个页面的*敏*感*词*姐
def get_meizi_url(html):
soup = BeautifulSoup(html, 'html.parser')
ol = soup.find('ol', attrs={'class': 'commentlist'})
href = ol.findAll('a', attrs={'class': 'view_img_link'})
for a in href:
download_pic(a['href'])
if __name__ == '__main__':
ssl._create_default_https_context = ssl._create_unverified_context
if not os.path.exists(pic_save_path):
os.makedirs(pic_save_path)
browser_get()
操作结果:
看看我们的输出文件夹~
学习Python爬虫,越来越瘦……
4.PhantomJS
PhantomJS 没有界面浏览器,特点:会将网站加载到内存中并执行
JavaScript,因为它不显示图形界面,所以它比完整的浏览器运行效率更高。
(如果某些 Linux 主机上没有图形界面,则无法安装 Chrome 等浏览器。
这个问题可以通过 PhantomJS 来规避)。
在 Win 上安装 PhantomJS:
在 Ubuntu/MAC 上安装 PhantomJS:
sudo apt-get install phantomjs
!!!关于 PhantomJS 的重要说明:
今年 4 月,Phantom.js 的维护者宣布退出 PhantomJS。
这意味着该项目可能不再维护!!!Chrome 和 FireFox 也开始了
提供Headless模式(不需要挂浏览器),所以估计用PhantomJS的小伙伴
会慢慢迁移到这两个浏览器。Windows Chrome 需要 60 以上的版本才能支持
Headless 模式,启用 Headless 模式也很简单:
selenium 的官方文档中还写道:
运行时也会报这个警告:
5.Selenium实战:模拟登录CSDN并保存Cookie
CSDN登录网站:
分析页面结构,不难发现对应的登录输入框和登录按钮:
我们要做的就是在这两个节点输入账号密码,然后触发登录按钮,
同时将Cookie保存在本地,以后就可以用Cookie访问相关页面了~
首先写一个方法来模拟登录:
找到输入账号密码的节点,设置你的账号密码,然后找到login
按钮节点,点击一次,然后等待登录成功,登录成功后可以对比
current_url 是否已更改。然后在这里保存 Cookies
我用的是pickle库,你可以用其他的,比如json,或者字符串拼接,
然后保存到本地。如果没有意外,应该可以拿到Cookie,然后使用
Cookie 访问主页。
通过 add_cookies 方法设置 Cookie。参数是字典类型的。此外,您必须首先
访问get链接一次,然后设置cookie,否则会报无法设置cookie的错误!
通过查看右下角是否变为登录状态就可以知道是否使用Cookie登录成功:
6.Selenium 常用函数
Seleninum 作为自动化测试的工具,自然提供了很多自动化操作的功能。
下面是我觉得比较常用的功能,更多的可以看官方文档:
官方API文档:
1) 定位元素
PS:将元素更改为元素将定位所有符合条件的元素并返回一个列表
例如:find_elements_by_class_name
2) 鼠标操作
有时需要在页面上模拟鼠标操作,例如:单击、双击、右键单击、按住、拖动等。
您可以导入 ActionChains 类:mon.action_chains.ActionChains
使用 ActionChains(driver).XXX 调用对应节点的行为
3) 弹出窗口
对应类:mon.alert.Alert,感觉用的不多...
如果触发到一定时间,弹出对话框,可以调用如下方法获取对话框:
alert = driver.switch_to_alert(),然后可以调用以下方法:
4)页面前进、后退、切换
切换窗口:driver.switch_to.window("窗口名称")
或者通过window_handles来遍历
用于 driver.window_handles 中的句柄:
driver.switch_to_window(句柄)
driver.forward() #forward
driver.back() # 返回
5) 页面截图
driver.save_screenshot("Screenshot.png")
6) 页面等待
现在越来越多的网页使用Ajax技术,所以程序无法判断一个元素什么时候完全
加载完毕。如果实际页面等待时间过长,某个dom元素还没有出来,但是你的
代码直接使用这个WebElement,会抛出NullPointer异常。
为了避免元素定位困难,增加ElementNotVisibleException的概率。
所以Selenium提供了两种等待方式,一种是隐式等待,一种是显式等待。
显式等待:
显式等待指定某个条件,然后设置最大等待时间。如果不是这个时候
如果找到该元素,则会抛出异常。
from selenium import webdriver
from selenium.webdriver.common.by import By
# WebDriverWait 库,负责循环等待
from selenium.webdriver.support.ui import WebDriverWait
# expected_conditions 类,负责条件出发
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.PhantomJS()
driver.get("http://www.xxxxx.com/loading")
try:
# 每隔10秒查找页面元素 id="myDynamicElement",直到出现则返回
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "myDynamicElement"))
)
finally:
driver.quit()
如果不写参数,程序默认会调用0.5s来检查元素是否已经生成。
如果原创元素存在,它将立即返回。
下面是一些内置的等待条件,你可以直接调用这些条件,而不是自己调用
写一些等待条件。
标题_是
标题_收录
Presence_of_element_located
visibility_of_element_located
可见性_of
Presence_of_all_elements_located
text_to_be_present_in_element
text_to_be_present_in_element_value
frame_to_be_available_and_switch_to_it
invisibility_of_element_located
element_to_be_clickable – 显示并启用。
staleness_of
element_to_be_selected
element_located_to_be_selected
element_selection_state_to_be
element_located_selection_state_to_be
alert_is_present
隐式等待:
隐式等待比较简单,就是简单的设置一个等待时间,以秒为单位。
from selenium import webdriver
driver = webdriver.PhantomJS()
driver.implicitly_wait(10) # seconds
driver.get("http://www.xxxxx.com/loading")
myDynamicElement = driver.find_element_by_id("myDynamicElement")
当然,如果不设置,则默认等待时间为0。
7.执行JS语句
driver.execute_script(js 语句)
例如,滚动到底部:
js = document.body.scrollTop=10000
driver.execute_script(js)
概括
本节讲解一波使用Selenium自动化测试框架抓取JavaScript动态生成的数据,
Selenium 需要依赖第三方浏览器,注意过时的 PhantomJS 无界面浏览器
对于问题,可以使用Chrome和FireFox提供的HeadLess来替换;通过抓住煎蛋女孩
模拟CSDN自动登录的图片和例子,熟悉Selenium的基本使用,或者收很多货。
当然Selenium的水还是很深的,目前我们可以用它来应对JS动态加载数据页面
数据采集就够了。
另外,最近天气很冷,记得及时补衣服哦~
顺便写下你的想法:
下载本节源码:
本节参考资料:
来吧,Py 交易
如果想加群一起学Py,可以加智障机器人小猪,验证信息收录:
python,python,py,py,添加组,事务,关键词之一即可;
验证通过后回复群获取群链接(不要破解机器人!!!)~~~
欢迎像我一样的Py初学者,Py大神加入,愉快交流学习♂学习,van♂转py。