大家好,我是不温卜火,是一名计算机学院大数据专业大三的学生,昵称来源于成语—不温不火,本意是希望自己性情温和。作为一名互联网行业的小白,博主写博客一方面是为了记录自己的学习过程,另一方面是总结自己所犯的错误希望能够帮助到很多和自己一样处于起步阶段的萌新。但由于水平有限,博客中难免会有一些错误出现,有纰漏之处恳请各位大佬不吝赐教!暂时只在 csdn 这一个平台进行更新,博客主页:https://buwenbuhuo.blog.csdn.net/。
**PS:由于现在越来越多的人未经本人同意直接爬取博主本人文章,博主在此特别声明:未经本人允许,禁止转载!!!**
@TOC
推荐
  ♥各位如果想要交流的话,可以加下 QQ 交流群:974178910,里面有各种你想要的学习资料。♥
  ♥欢迎大家关注公众号【不温卜火】,关注公众号即可以提前阅读又可以获取各种干货哦,同时公众号每满 1024 及 1024 倍数则会抽奖赠送机械键盘一份+IT 书籍 1 份哟~♥
一、小小课堂
经过上篇的简单介绍,相信你们已经对 selenium 有了初步的了解,那么!为了让大家对 selenium 有进一步的了解。细心的博主给大家带来了福利,那就是使用 selenium 爬取百度妹子图。希望大家不要叫我 LSP!
至于通过怎样的思路爬取百度妹子图呢?博主的大体思路是先获取一定量的内容保存成 html 页面,然后通过解析已经保存的 html 中的图片链接,然后保存到本地。
二、保存内容成 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"#垂直滚动 pxscroll = "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)
复制代码
在此,博主使用了滑动到指定坐标。由于已经验证过了,所以直接给出正确游标
效果图如下:
在此,博主先测试翻页 10 次,代码如下
for i in range(10): #执行js driver.execute_script("window.scrollTo(0,10000)") time.sleep(1)
复制代码
效果图:
好了,所有的准备工作,我们已经完成了。那么接下来我们只需把他保存为 html 页面即可。
2.2 此部分完整代码
from selenium import webdriverfrom lxml import etreeimport osimport timeimport requestsimport reimport 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 为例,所以其他的都不在自行查找了。
在提取图片的 URL 之前,我们先查看下是不是我们所要的图片,随便打开一个
如:https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=3026930057,3755157843&fm=26&gp=0.jpg
🆗,正是我们所需要的图片,下面就可以开始提取了。
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''' @author 李华鑫 @create 2020-10-10 9:26 Mycsdn:https://buwenbuhuo.blog.csdn.net/ @contact: 459804692@qq.com @software: Pycharm @file: 原始版本.py @Version:1.0 '''from selenium import webdriverfrom lxml import etreeimport osimport timeimport requestsimport reimport 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''' @author 李华鑫 @create 2020-10-10 9:27 Mycsdn:https://buwenbuhuo.blog.csdn.net/ @contact: 459804692@qq.com @software: Pycharm @file: 添加代理IP.py @Version:1.0 '''from selenium import webdriverfrom lxml import etreeimport osimport timeimport requestsimport reimport 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()
复制代码
美好的日子总是短暂的,虽然还想继续与大家畅谈,但是本篇博文到此已经结束了,如果还嫌不够过瘾,不用担心,我们下篇见!
  好书不厌读百回,熟读课思子自知。而我想要成为全场最靓的仔,就必须坚持通过学习来获取更多知识,用知识改变命运,用博客见证成长,用行动证明我在努力。
  如果我的博客对你有帮助、如果你喜欢我的博客内容,请“点赞” “评论”“收藏”一键三连哦!听说点赞的人运气不会太差,每一天都会元气满满呦!如果实在要白嫖的话,那祝你开心每一天,欢迎常来我博客看看。
  码字不易,大家的支持就是我坚持下去的动力。点赞后不要忘了关注我哦!
评论