这里我们使用的是selenium+driver 这个方法通俗的说就是模拟人去百度查找图片,内容比较多,但是很实用,希望大家能看完,必定受益匪浅。

一、知识前提

我们需要了解一些概念1.什么是selenium?

selenium是网页自动化测试工具,可以自动化的操作浏览器。如果需要操作哪个浏览器需要安装对应的driver,比如你需要通过selenium操作chrome,那必须安装chromedriver,而且版本与chrome保持一致。

2、driver

操作浏览器的驱动,分为有界面和无界面的

有界面:与本地安装好的浏览器一致的driver(用户可以直接观看,交互比如单击、输入)

无界面:phantomjs(看不到,只能通过代码操作,加载速度比有界面的要快)

了解完之后,安装selenium:

pip install selenium -i https://pypi.tuna.tsinghua.edu.cn/simple

为了让大家对selenium有进一步的了解。细心的博主给大家带来了福利,那就是使用selenium爬取百度妹子图。为了大家不把我当成LSP,我把妹子图片换成了哆啦A梦,希望大家不要叫我LSP!

二、保存内容成html

2.1 通过selenium模拟普通人查找百度图片

1. 普通人搜索图片



2 分析

知道了普通人如何查找图片,那么我们下面就通过selenium模拟上述的具体过程。在模拟之前,我们先分析一下几个主要的点。

1. 输入框

我们通过打开开发者选项,找到输入框所在部分,解析xpath

2. 查询点击

3. 点击关于美女的百度图片

3 代码实现

# 控制chrome浏览器

driver = webdriver.Chrome("./chromedriver/chromedriver.exe")

#窗口最大化

driver.maximize_window()

# 输入网址

driver.get("https://www.baidu.com/")

# 找到文本框,输入文字

driver.find_element_by_xpath('//*[@id="kw"]').send_keys("哆啦a梦图片")

#找到按钮,单击

driver.find_element_by_xpath('//*[@id="su"]').click()

#停一下,等待加载完毕

time.sleep(2)

#找到a标签,单击

driver.find_element_by_xpath('//*[@id="1"]/h3/a').click()

#停一下,等待加载完毕

time.sleep(2)


,我们可以看到已经完美的模拟出来过程。


在这里我们看效果是很不错的,但是其实还是有点小问题的,我们现在其实还只是在第一个窗口中,因此我们需要切换一下的窗口,这个时候我们就需要添加下面一行代码

#切换窗口,因为现在打开了一个窗口,目前还是在第1个窗口中

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

4 模拟人为鼠标滑轮滚动屏幕

模拟人为鼠标滑轮滚动屏幕,我们有Selenium+python自动化之js屏幕滑动,下列为脚本实现js滑屏

scroll="document.documentElement.scrollTop=800"#垂直滚动 px

scroll = "document.documentElement.scrollLeft=1000"#水平滚动

scroll="window.scrollTo(0,10000)"#滚动到指定坐标

scroll="window.scrollBy(0,100)"#滑动到相对坐标

scroll="window.scrollTo(0,document.body.scrollHeight)"#获取body的高度,滑到底部

document.body.scrollWidth 获取body宽度

driver.execute_script(scroll)

在此,我使用了滑动到指定坐标。由于已经验证过了,所以直接给出正确游标

window.scrollTo(0,10000)

效果图如下:


在此,我先测试翻页10次,代码如下

for i in range(10):

#执行js

driver.execute_script("window.scrollTo(0,10000)")

time.sleep(1)

效果图:

好了,所有的准备工作,我们已经完成了。那么接下来我们只需把他保存为html页面即可。

2.2 此部分完整代码

from selenium import webdriver
from lxml import etree
import os
import time
import requests
import re
import random
#
headers = {
"user-agent": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",
}
#创建文件夹
if not os.path.exists("./files/baidu"):
os.makedirs("./files/baidu")
def get_html():
# 控制chrome浏览器
driver = webdriver.Chrome("./chromedriver/chromedriver.exe")
#窗口最大化
driver.maximize_window()
# 输入网址
driver.get("https://www.baidu.com/")
# 找到文本框,输入文字
driver.find_element_by_xpath('//*[@id="kw"]').send_keys("哆啦a梦图片")
#找到按钮,单击
driver.find_element_by_xpath('//*[@id="su"]').click()
#停一下,等待加载完毕
time.sleep(2)
#找到a标签,单击
driver.find_element_by_xpath('//*[@id="1"]/h3/a').click()
#停一下,等待加载完毕
time.sleep(2)
#切换窗口,因为现在打开了一个窗口,目前还是在第1个窗口中
driver.switch_to.window(driver.window_handles[1])
for i in range(10):
#执行js
driver.execute_script("window.scrollTo(0,10000)")
time.sleep(1)
#获取页面html
html = driver.page_source
# 关闭
driver.quit()
#保存html
with open("baidu.html","w",encoding="utf-8") as file:
file.write(html)
return html
if __name__ == '__main__':
get_html()

2.3 保存HTML并查看是否保存成功


到这里,我们的保存工作就已经完成了,下面就需要对其进行解析了。

三、解析图片链接

3.1 前期分析

在此先给出所以能够爬取的图片URL,然后进行分析,如何得到

data-objurl="http://pic.jj20.com/up/allimg/1113/041620103S8/200416103S8-4-1200.jpg"

data-imgurl="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1948216838,2050876637&fm=26&gp=0.jpg">

"hoverURL":"https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1948216838,2050876637&fm=26&gp=0.jpg"

"thumbURL":"https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1672252528,4061027335&fm=26&gp=0.jpg"

"middleURL":"https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1672252528,4061027335&fm=26&gp=0.jpg"

我们首先先把得到的html打印出来,然后通过查找URL,找到图片的URL即可

由于本次只以此两个URL为例,所以其他的都不在自行查找了。

,正是我们所需要的图片,下面就可以开始提取了。

3.2 正则提取URL

#读数据

with open("baidu.html", "r", encoding="utf-8") as file:

html = file.read()

#通过正则获取img url

img_list1 = re.findall(r'data-objurl="(.*?)"', html)

img_list2 = re.findall(r'data-imgurl="(.*?)"', html)

#合并

img_list1.extend(img_list2)

print(img_list2)

现在我们先打开URL,看看能不能打开。

结果我们发现有的URL并不能打开,这是正常的,因为各种原因总会有某些URL无法打开,这时候我们先多找几个URL试验即可。

但是直接这样看的话,并不好看,这个时候我们需要把他遍历并打印所有的URL

#替换部分不需要的字符

img_list = map(lambda x:x.replace("amp;",""),img_list1)

#遍历

for img in img_list:

print(img)

time.sleep(random.random()*3)

然后查看结果

,到这里我们所有需要分析的部分都已经分析完成了。

四、完整代码


# encoding: utf-8
'''
2020最新python学习资源分享:1156465813
'''
from selenium import webdriver
from lxml import etree
import os
import time
import requests
import re
import random
headers = {
"user-agent": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",
}
#创建文件夹
if not os.path.exists("./files/baidu"):
os.makedirs("./files/baidu")
def get_html():
# 控制chrome浏览器
driver = webdriver.Chrome("./chromedriver/chromedriver.exe")
#窗口最大化
driver.maximize_window()
# 输入网址
driver.get("https://www.baidu.com/")
# 找到文本框,输入文字
driver.find_element_by_xpath('//*[@id="kw"]').send_keys("美女")
#找到按钮,单击
driver.find_element_by_xpath('//*[@id="su"]').click()
#停一下,等待加载完毕
time.sleep(2)
#找到a标签,单击
driver.find_element_by_xpath('//*[@id="1"]/h3/a').click()
#停一下,等待加载完毕
time.sleep(2)
#切换窗口,因为现在打开了一个窗口,目前还是在第1个窗口中
driver.switch_to.window(driver.window_handles[1])
for i in range(10):
#执行js
driver.execute_script("window.scrollTo(0,10000)")
time.sleep(1)
#获取页面html
html = driver.page_source
# 关闭
driver.quit()
#保存html
with open("baidu.html","w",encoding="utf-8") as file:
file.write(html)
return html
def get_data():
#读数据
with open("baidu.html", "r", encoding="utf-8") as file:
html = file.read()
#通过正则获取img url
img_list1 = re.findall(r'data-objurl="(.*?)"', html)
img_list2 = re.findall(r'data-imgurl="(.*?)"', html)
#合并
img_list1.extend(img_list2)
#替换部分不需要的字符
img_list = map(lambda x:x.replace("amp;",""),img_list1)
#遍历
for img in img_list:
print(img)
time.sleep(random.random()*3)
#获取图片字节,可能被拦截,加上代理ip
content = requests.get(img,headers=headers).content
#文件的名字
filename = "./files/baidu/{}".format(img.split("/")[-1])
#文件写
with open(filename,"wb") as file:
file.write(content)
if __name__ == '__main__':
get_html()
get_data()
# data-objurl="http://pic.jj20.com/up/allimg/1113/041620103S8/200416103S8-4-1200.jpg"
# data-imgurl="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1948216838,2050876637&fm=26&gp=0.jpg">
# "hoverURL":"https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1948216838,2050876637&fm=26&gp=0.jpg"
# "thumbURL":"https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1672252528,4061027335&fm=26&gp=0.jpg"
# "middleURL":"https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1672252528,4061027335&fm=26&gp=0.jpg"

五、爬取结果



但是! 我们这样爬取的话,过一段时间就会被识别出来。如下图:


这个时候,我们最好加上代理IP 。进行循环爬取。

六、修改版源码(加上代理IP)


# encoding: utf-8
'''
2020最新python学习资源分享:1156465813
'''
from selenium import webdriver
from lxml import etree
import os
import time
import requests
import re
import random
headers = {
"user-agent": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",
}
#创建文件夹
if not os.path.exists("./files/baidu"):
os.makedirs("./files/baidu")
def get_html():
# 控制chrome浏览器
driver = webdriver.Chrome("./chromedriver/chromedriver.exe")
#窗口最大化
driver.maximize_window()
# 输入网址
driver.get("https://www.baidu.com/")
# 找到文本框,输入文字
driver.find_element_by_xpath('//*[@id="kw"]').send_keys("哆啦A梦图片")
#找到按钮,单击
driver.find_element_by_xpath('//*[@id="su"]').click()
#停一下,等待加载完毕
time.sleep(2)
#找到a标签,单击
driver.find_element_by_xpath('//*[@id="1"]/h3/a').click()
#停一下,等待加载完毕
time.sleep(2)
#切换窗口,因为现在打开了一个窗口,目前还是在第1个窗口中
driver.switch_to.window(driver.window_handles[1])
for i in range(10):
#执行js
driver.execute_script("window.scrollTo(0,10000)")
time.sleep(1)
#获取页面html
html = driver.page_source
# 关闭
driver.quit()
#保存html
with open("baidu.html","w",encoding="utf-8") as file:
file.write(html)
return html
def get_proxies():
#这里获取的芝麻HTTP代理http https\\
time.sleep(2+random.random()*3)
proxies = {
"http": "",
"https": ""
}
url = "http://http.tiqu.alicdns.com/getip3?num=1&type=2&pro=&city=0&yys=0&port=11&time=1&ts=0&ys=0&cs=1&lb=1&sb=0&pb=45&mr=1®ions="
response = requests.get(url)
content = response.json()
proxies["https"] = content["data"][0]["ip"]+":"+str(content["data"][0]["port"])
return proxies
def get_content(url):
"""发送请求获取数据"""
#如果报错,停一会,再发,有10次机会,否则返回空字节
for i in range(5):
try:
# 获取图片字节,可能被拦截,加上代理ip
return requests.get(url, headers=headers, proxies=get_proxies()).content
except:
print(url, "失败,尝试第{}次".format(i + 1))
time.sleep(random.random()*5)
return b""
def get_data():
#读数据
with open("baidu.html", "r", encoding="utf-8") as file:
html = file.read()
#通过正则获取img url
img_list1 = re.findall(r'data-objurl="(.*?)"', html)
img_list2 = re.findall(r'data-imgurl="(.*?)"', html)
#合并
img_list1.extend(img_list2)
#替换部分不需要的字符
img_list = map(lambda x:x.replace("amp;",""),img_list1)
#遍历
for img in img_list:
print(img)
content = get_content(url=img)
#文件的名字
filename = "./files/baidu/{}".format(img.split("/")[-1])
#文件写
with open(filename,"wb") as file:
file.write(content)
if __name__ == '__main__':
#get_html()
get_data()

到现在,完整的代码已经完成了,如果爬妹子的图片,在代码里面把哆啦A梦改成妹子就可以了