输入关键字 抓取所有网页(如何实现代码访问关键词搜索的问题解决差不多(组图))

优采云 发布时间: 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

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线