python爬虫爬取桌面壁纸

  • A+
所属分类:网站建设

壁纸网站wall.alphacoders.com,一个分享高清图片壁纸的网站,国内的链接速度那叫一个慢,尤其是其网站的原图都是2K、4k的加载起来是在是慢的不要不要的,于是想用VPS爬去图片后在下载到本地下面简单记录一下
一、请求分析
首先我们F12打开开发者工具,在一张图上找到下载
python爬虫爬取桌面壁纸|青衣楼
我们在开发者工具里面取元素,并没有看到下载链接,说明下载链接并没有包含在原始html中,但是点击是可以下载的,并且可以看到整个页面并没有进行刷新,判断是一个ajax请求,直接点进XHR,然后再次点击下载链接可以看到请求。
python爬虫爬取桌面壁纸|青衣楼
可以看到这个请求返回了一个链接,我们直接访问链接,发现是可以下载的,说明这就是下载链接了,那么这个链接是怎么来的呢?
python爬虫爬取桌面壁纸|青衣楼
我们看看请求,这个post请求里面有一些参数,我们先不去考虑这些参数怎么来的,我们先模拟一下请求看看请求Header里面有没有什么东西是必须的,这里直接上postman或者curl都可以,如果你的机器上面安装了curl我推荐用这个,因为Chrome开发者工具,直接可以在请求上右键Copy as cURL,直接可以帮你复制出curl命令,我这里复制出来是这样的

  1. curl "https://wall.alphacoders.com/get_download_link.php" -H "Pragma: no-cache" -H "Origin: https://wall.alphacoders.com" -H "Accept-Encoding: gzip, deflate, br" -H "Accept-Language: zh-CN,zh;q=0.9" -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36" -H "Content-Type: application/x-www-form-urlencoded; charset=UTF-8" -H "Accept: */*" -H "Cache-Control: no-cache" -H "X-Requested-With: XMLHttpRequest" -H "Cookie: __cfduid=d7ec945393d1b5ef3c28d4c9d12ef9fb11552315444; cookieconsent_status=allow; wa_session=1eogv8ehgn3itq5g4g8hfsducpkm9lbu46q893vrkhph3ued4rm89gvk7ck4fdg9k73cmrcdesoqj4crm1575vj3lfid9e67fpis661" -H "Connection: keep-alive" -H "Referer: https://wall.alphacoders.com/search.php?search=Asuna" --data "wallpaper_id=533007^&type=png^&server=images8^&user_id=79150" --compressed

我们先去掉不必要的东西 curl "https://wall.alphacoders.com/get_download_link.php" --data "wallpaper_id=533007&type=png&server=images8&user_id=79150" ,直接执行,发现可以获取到地址,所以现在要考虑的只有这些参数是怎么来的了,下面我同样放一张postman的图,可以看到是同样的可以获取到下载链接
python爬虫爬取桌面壁纸|青衣楼
python爬虫爬取桌面壁纸|青衣楼
和上面的post参数是一一对应的。
所以爬取思路就出来了。
访问一个页面,取到每一个图的特定属性,然后构造post请求得到下载地址,然后访问地址下载图片
那新问题是如果进行翻页并且判断是否到了最后一页。
我们可以发现页数是通过get的网址决定的,https://wall.alphacoders.com/search.php?search=asuna&page=10 ,更改page后面的值即可。
判断是否到了尾页,我们可以打开最后一页,然后查看一下html,我们可以看到下一页按钮的链接已经变成了 Next > ·,那我们就可以根据href的值是否为 # 来判断了。
二、Python库的选择
唯一用到的第三方库就是 Requests ,以前解析html的Dom树喜欢用BeautifulSoup,但是后来发现解析速度上确实和re有很大差距,并且当html有很特殊的字符时会又是莫名出错,故工程量不大的情况下,我现在还是优选正则。
上代码

  1. #coding=utf-8
  2. import requests
  3. import re
  4. import os
  5. import sys
  6. proxies = { "http""http://127.0.0.1:1080""https""http://127.0.0.1:1080", }
  7. #proxies = {}
  8. download_dir = './pic/'
  9. downloaded_num = 0
  10. total = 0
  11. def download_pic(url, name, pic_type):
  12.     global proxies
  13.     global download_dir
  14.     global downloaded_num
  15.     global total
  16.     # if dir isn't exist, create a dir to download pic
  17.     if not os.path.exists(download_dir):
  18.         os.makedirs(download_dir)
  19.     # download pic to special dir
  20.     r = requests.get(url, proxies=proxies)
  21.     downloaded_num += 1
  22.     with open('%s/%s.%s'%(download_dir, name, pic_type), 'wb') as f:
  23.         f.write(r.content)
  24.     print('[{:5d}/{}] {}.{} Done!'.format(downloaded_num, total, name, pic_type))
  25. def get_download_link(wallpaper_id, wallpaper_type, server, user_id):
  26.     global proxies
  27.     post_data = {
  28.         'wallpaper_id': wallpaper_id,
  29.         'type': wallpaper_type,
  30.         'server': server,
  31.         'user_id': user_id,
  32.     }
  33.     r = requests.post('https://wall.alphacoders.com/get_download_link.php', data=post_data, proxies=proxies)
  34.     download_pic(r.text, wallpaper_id, wallpaper_type)
  35. def getwallpaper(keyword):
  36.     global proxies
  37.     global total
  38.     p_nextpage = re.compile(r"<a id='next_page' href=[\'\"](.+?)[\'\"]>")
  39.     p_item = re.compile(r'data-id="(\d+?)" data-type="(\w+?)" data-server="(\w+?)" data-user-id="(\d+?)"')
  40.     page_num = 1
  41.     while 1:
  42.         r_page = requests.get('https://wall.alphacoders.com/search.php?search=%s&lang=Chinese&page=%d' % (keyword.lower(), page_num), proxies=proxies)
  43.         nextpage_link = p_nextpage.search(r_page.text)
  44.         # if there isn't any search result, it will exit the loop
  45.         if nextpage_link == None:
  46.             print("Sorry, we have no results for your search!")
  47.             break
  48.         if page_num == 1:
  49.             total = int(re.search(r"<h1 class='center title'>\s+?(\d+)(.+?)\s+?</h1>", r_page.text).group(1))
  50.             print("the %s wallpaper's total is %d" % (keyword, total))
  51.         for item in p_item.findall(r_page.text):
  52.             wallpaper_id = item[0]
  53.             wallpaper_type = item[1]
  54.             server = item[2]
  55.             user_id = item[3]
  56.             get_download_link(wallpaper_id, wallpaper_type, server, user_id)
  57.         # if there isn't the next page's link, it will exit the loop
  58.         if nextpage_link.group(1) == '#':
  59.             print("All wallpaper done!")
  60.             break
  61.         page_num += 1
  62. if __name__ == '__main__':
  63.     if len(sys.argv) < 2 or len(sys.argv) > 3:
  64.         usage_text = "Usage:\n\tpython getwallpaper.py miku [miki_pic]\nFirst param: the name of script\nSecond param: the wallpaper's keyword which you want to search\nThird param: the dir's name where you want to download in, optional, default in ./pic"
  65.         print(usage_text)
  66.     elif len(sys.argv) == 3:
  67.         download_dir = str(sys.argv[2])
  68.         getwallpaper(str(sys.argv[1]))
  69.     else:
  70.         getwallpaper(str(sys.argv[1]))

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: