python 爬取https://wall.alphacoders.com上的壁纸

0,环境

python3.7
库:requests,BeautifulSoup4

1,目标

https://wall.alphacoders.com/popular_searches.php

python爬取跨域请求数据 python爬取https_爬虫


这是网页search页面上前面几个热搜

python爬取跨域请求数据 python爬取https_python爬取跨域请求数据_02


点开第一个里面有很多图片,

目标就是爬取热搜前十所有这些壁纸

2,网站源码分析:批量获取热搜网址

先要获取热搜的网址:

进入https://wall.alphacoders.com/popular_searches.php 打开开发者选项F12

python爬取跨域请求数据 python爬取https_python_03


(有点不清晰,关键信息已经画出来了)

python爬取跨域请求数据 python爬取https_开发语言_04


网址所在节点特征:

1)顶上是h3,其class=“search-term”

2)网址在这个h3子节点a标签中的href中

于是有了相关代码:

# search.py
import requests
from bs4 import BeautifulSoup


def search_all(url="https://wall.alphacoders.com/popular_searches.php", index=10):
    html = requests.get(url) # index:排名数默认10,url指定了.
    soup = BeautifulSoup(html.text, "lxml") 
    n = index 
    url_list = [] #存储热搜网址的列表
    for i in soup.find_all(name='h3', attrs={'class': 'search-term'}): #寻找符合条件的父节点
        url1: str = i.a["href"] #获取i的第一个a子节点的href属性值
        url_list.append(url1)
        n = n - 1
        if n == 0:
            return url_list #个数到了就返回
    return url_list


if __name__ == "__main__":
    print(search_all())

3,网站源码分析:批量获取图片

python爬取跨域请求数据 python爬取https_爬虫_05

<img class="img-responsive big-thumb"   width="600" height="375"   src="https://images3.alphacoders.com/102/thumbbig-102135.jpg" alt="Earth Landscape HD Wallpaper | Background Image">

可以看出特征有如下几点:

  1. 标签名为img
  2. class = “img-responsive big-thumb”
  3. 网址在src属性值中

于是有了代码:

# main.py (与search.py同目录)
import requests
import threading
import time
from search import search_all
# import re
from bs4 import BeautifulSoup


class Spider:
    def __init__(self, web="https://wall.alphacoders.com/search.php?search=landscape"):
        self.web = web

    def get_one(self):
        html = requests.get(self.web)
        soup = BeautifulSoup(html.text, 'lxml')
        for i in soup.find_all(name='img', attrs={'class': 'img-responsive'}):
            url = i['src'] #获取图片网址

            threading.Thread(target=Downloader(url).work).start() #关于多线程用法自行学习,如不熟的可以改成Downloader(url).work()


# 封装事务
class Downloader:
    def __init__(self, url):
        self.url = url
        print(f"At :{url}")

    def work(self):
        print(f"start..{self.url}")
        name = self.url.split('/')[-1] # 获取网址对应的文件名
        with open(f"image/{name}", 'wb') as f:
            f.write(requests.get(self.url).content) # get网址内容并以二进制形式写入相应文件
        print(f"end..{self.url}")


if __name__ == "__main__":
    
    urls = search_all()
    for j in urls:
        threading.Thread(target=Spider(web=j).get_one).start()

项目结构如下:(一定要提前创建一个image文件夹, image.zip不需要啊)

python爬取跨域请求数据 python爬取https_php_06


注意!

1,main.py里面几乎都是采用多线程下载,速度虽然提升了

但开销非常大,建议电脑配置不好的将main.py最后几行代码改成阻塞代码即:

if __name__== "__main__":
	t1 = time.time()
    urls = search_all()
    for j in urls:
        Spider(web=j).get_one()
    print(f"use: {time.time()-t1} s")

2,代码编辑可以在pycharm里面,但最好在外面的命令行跑main.py 因为我的pycharm因此死机了…

跑的结果:

python爬取跨域请求数据 python爬取https_python爬取跨域请求数据_07


控制台输出没有截图.

4,后记

爬图如此《顺利》原因:
网站似乎并没有对频繁同IP请求进行封杀
甚至User-Agent也没有伪装
如果有兴趣的同学可以查一查如何伪装IP和请求头.