输入关键字 抓取所有网页(如何实现代码访问关键词搜索的问题解决差不多(组图))
优采云 发布时间: 2021-12-26 01:14输入关键字 抓取所有网页(如何实现代码访问关键词搜索的问题解决差不多(组图))
- 与关键字的链接:
对比后可以发现/search?q=alita多了,alita是手动输入关键词,规律其实很明显,再找个例子验证一下
- 与关键字的链接:
在首页输入关键词aabb搜索到的页面,添加一个组合链接页面,相当于在后面添加/search?q=aabb。至此,如何解决搜索代码访问关键词的问题差不多有了一个思路,代码如下:
代码在所有分析完成后编写。分析到这一步时,它不会立即写入。贴在这里是为了更好地理解。分析的时候做个笔记,不然写代码的时候忘记重新验证会很费时间。
当你搜索关键词后的页面欣赏图片时,向下滑动。细心的话,会发现页面暂停了一段时间,地址栏也发生了变化,如下图:
看看地址变成了:
&page=2
添加地址的 &page=2 部分。事实上,当页面关闭时,页面会翻转并刷新。那么,根据之前的经验,页面会不会控制粗体部分的页码呢?
将page的值赋值为1,验证后发现确实是第一页。然后我们可以通过代码改变page的值来控制页码。这样我们就可以通过page遍历关键词搜索到的所有图片页码,然后遍历所有图片。
在这里,有一个问题。如果知道总页数,就可以遍历循环,但是如何得到总页数是个问题,在后续的网站分析中应该有意识地去寻找这个问题。
默认情况下,现在我们可以搜索关键词,并且已经按照页码遍历了所有图片,那么思路应该是遍历获取每张图片的链接,然后通过图片链接下载图片。
-->分析图片中存储的标签
打开开发者工具,选择一张图片查看网页代码,发现每张图片的各种信息都保存在ul下的li标签中,图片链接也放在href中。现在好像图片链接也能找到了,思路看起来很清晰,想办法遍历获取链接然后下载,不过还是去目标链接的页面看看
目标页面不仅仅是一张图片,而是这张图片的详细页面。再次打开开发者工具定位图片找到的图片链接就是这张图片的链接,比如这张图片的链接:
也就是说,现在我们需要再访问一次页面才能得到图片的链接。写代码考虑的比较多,出错的可能性比较大,运行时间比较长等等。如果只能访问一个页面,并保存一页图片的所有最终地址,工作量会少很多。
仔细对比图片的初始链接和最终链接,发现最终图片链接所需的关键信息可以在初始链接中找到。也就是说,我们完全可以通过初始链接重新组织图片的最终链接,避免再次访问页面的麻烦。
-->最后的图片链接的关键信息是什么,我们找一组来分析:
最后两个链接对比发现,除了关键字1j和1jrpkv的位置和图片的后缀外,其他部分都是一样的。jpg 和 png 两个后缀的问题只需要在异常处理部分解决,这里就不赘述了。解决。而这一关键信息部分位于初始链接的末尾。至此,二次访问的问题就解决了,通过访问一个页面重新组织最终的图片链接,就可以得到该页面所有图片的所有关键信息。除了从初始链接中提取这个关键字外,还可以在figure标签的data-wallpaper-id属性的值中找到,如图:
我选择获取属性值,因为这样可以直接获取关键字,无需提取。至此,获取图片真实链接的问题已经较好的解决了。具体的获取和重组是通过代码实现的。这只是分析。现在如果能知道搜索结果的页码,分析网站的工作就快结束了。
页面至少刷新一次后,会出现页码标签,如图:
通过定位页面来获取总页数的信息并不难,但是如果这样做,就必须翻页。想象一下结果的图片较少并且不足以翻页的情况。这种情况需要判断和特殊处理,比较麻烦。,但并非不可行。
然后看看有没有更简单的方法。通过观察发现,结果的分布是每页有24张图片。获取到这些信息后,获取总页数的问题就变成了获取图片总数的问题,获取总数很简单:
搜索开始后的页面,显示图片总数。开发者模式定位这个号码的位置:
解决了总页数的问题。至此,网站分析的水平已经足以支撑我们完成这次图片的自动下载。当然,如果我们花更多的时间分析,也许我们可以得到更好的解决方案,并提出新的想法。
--> 最后总结一下分析的结果,我们找到了关键词的真实链接合成方式,控制搜索结果的翻页方式,找到获取每张图片的链接方式。
4.代码实现
本文重点分析过程,即爬虫如何执行必要的工作,同一个思想的爬虫代码实现有很多种,代码就不一一解释了:
import
def get_html(url):
'''
本函数获取目标链接页面
参数 :
url : 目标链接
'''
try :
kvs = [
'''Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36''',
'''Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36''',
'''Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.1 Safari/537.36''',
'''Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.0 Safari/537.36''',
'''Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.0 Safari/537.36'''
] # 浏览器标识
user_agent = random.choice(kvs) # 每次随机选一个
headers = {"User-Agent" : user_agent}
r = requests.get(url,headers = headers)
r.raise_for_status()
r.encoding = r.apparent_encoding
r = r.text
return r
except :
return ''
def down_url(info_list,keyword):
root = "D://{}//".format(keyword,keyword)
path = root + "{}.txt".format(keyword)
# 判断计算机是否有将要保存的文件夹
if not os.path.exists(root) :
os.mkdir(root) # 没有的话创建
for info in info_list :
with open(path,"a") as f :
f.write(info+"n")
f.close()
def parser_html(url_html,info_list):
'''
解析 html 页面,获取每张图片的唯一标识
参数 :
url_html : 要解析的页面
info list : 存放标识的列表
'''
soup = BeautifulSoup(url_html,"html.parser")
for children in soup.find("section").ul.children :
info = children.find("figure").get("data-wallpaper-id")
info_1 = info[:2]
suf = ".png"
try :
children.find("figure").div("span")[1]
except :
suf = ".jpg"
url = "https://w.wallhaven.cc/full/"+info_1+"/wallhaven-"+info+suf
info_list.append(url) # 获取图片关键字
def down_image(info,keyword):
'''
根据标识下载图片
参数 :
info : 图片的标识
keyword : 输入的图片关键字
'''
kv = {'user-agent':'Mozilla/5.0'}
# info_1 = info[0:2]
root = 'D://{}//'.format(keyword) # 图片下载的文件夹
if not os.path.exists(root) :
os.mkdir(root) # 没有的话创建
path = root + info[31:51] # 命名并添加在路径
if not os.path.exists(path) :
# 没有的话下载
try :
r = requests.get(info,headers = kv)
r.raise_for_status()
except :
return
with open(path,'wb') as f :
f.write(r.content)
f.close
首先,为一些功能编写一个框架。在编写main函数时,完成这些功能。爬虫的主要工作是获取页面,解析页面,获取并保存信息。这些差不多就是爬虫的基本框架了,最后是主要功能。
def main():
# 获取搜索图片的关键字
keyword = input("请输入要下载图片的主题名字(英文) : ")
url = "https://wallhaven.cc/search?q="+keyword
url_html = get_html(url) # 获取目标链接的页面信息
soup = BeautifulSoup(url_html,"html.parser") # 解析页面
try :
num = re.findall(r"d+",soup.find("h1").get_text())[0] # 正则表达式提取图片总页数
except :
input("n发生异常,请检查网络,任意键结束:")
return
if num == '0' : # 图片总数为 0,给出提示,程序结束
print("n没有此关键词的图片 :")
input("n任意键结束 :")
return
flage = input("n共有 {} 张,输入 0 取消, 1 下载,其他任意键保存链接 : ".format(num)) # 提示总图片数,是否确认下载
if flage == '0' :
print("n下载已取消")
return
else :
print("n正在获取照片信息 : ")
print("n")
num_page = (int(num) // 24) + 1 # 获取总页数
info_list = []
for page in range(num_page) : # 遍历全部页码
url = "https://wallhaven.cc/search?q="+keyword+"&page={}".format(page+1)
url_html = get_html(url)
try :
parser_html(url_html,info_list)
except :
continue
i = 0
if flage == 1 :
print("n正在下载 : ")
try :
for info in info_list :
down_image(info,keyword)
i = i+1
num_1 = int((i / int(num))*35)
a = ">" * num_1
b = "." * (35-num_1) # 进度条
print("r[{}{}]{:3}%".format(a,b,'%.2f'%((i/int(len(info_list)))*100)),end="")
except :
input("n发生异常,请检查网络,任意键结束:")
input(r"nn图片保存至 D:{}nn任意键结束 :".format(keyword))
else :
try :
down_url(info_list,keyword)
except :
input("n发生异常,请检查网络,任意键结束:")
input("nn文件保存至 D:{}nnnn任意键结束 :".format(keyword))
main函数更多地体现了整体流程和异常处理。如果不写那些函数的框架,全写一堆代码,不容易发现错误和维护。其实最好在进度条里写一个单独的函数。我已经写完了。而且我很懒。
下载:
5. 最后的话
最近,有人出事了。我其实跟他不是很熟。我只用过他家的产品。没想到知道作者是因为这种事。他是一个非常有互联网头脑的人,而我是一个普通人。我什么也做不了,用我自己的方式致敬,仅此而已。
这也是我第一次写下载图片的爬虫。希望对对此领域感兴趣的新手有所帮助。文章来源转载,恕不另行通知,代码随意使用和处理。我没有公众号,没有引流,我只是分享。希望用过的人有新的想法和更好的方式回来交流,共同进步。
- 源代码
提取码:ydea