当前位置:   article > 正文

python通过url下载文件不可读_Pyhton爬虫的另类操作,之前有碰到不能爬的网页来看看!...

通过url下载的图片python读取不到

这里我们使用的是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&regions="

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梦改成妹子就可以了

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/912887
推荐阅读
相关标签
  

闽ICP备14008679号