爬取精美壁纸5w张,爱了爱了
近日接到一个需求——爬取某应用商店所有在线销售壁纸,这个任务起初让我惊呆了。因为上级没有给我解决风控问题,若爬取在售资源被人家厂商追责怎么办?若造成人家服务器出问题怎么办?问的时候上级含糊其辞,唉!其实大家都懂。但为什么我接了这个活儿呢,因为我随便发了几页,发现好多小姐姐壁纸,那种贼漂亮大波浪的你懂的,不愧是壁纸级小姐姐。
想要5万张小姐姐壁纸的单独联系我哦~
抛开资源本身,下面是具体的实现方法。这次不用scrapy,用requests实现的哦~
一. 登录
这种资源只有登录才能获取,所以我们得先过登录这一关。
起初我不知道是数万数量级的资源,人家给我说的自动化操作,我以为ui自动化可以实现,所以我用selenium的衍生库来模拟点击。
import time
from common.utils import GetDriver
from page import SumsungPage
from selenium.common.exceptions import NoSuchElementException page: SumsungPage def verify(func):
def wrapper(*args):
func(*args)
try:
if page.log_out.is_displayed():
return True
except NoSuchElementException:
return False return wrapper class SumsungLogin:
"""
**应用商店登录,优先cookie登录,cookie登录失败就用账号登录
""" def __init__(self):
global page
page = SumsungPage(GetDriver().driver()) @verify
def __account_login__(self):
"""
账号密码登录
"""
page.get(page.url)
page.entry.click()
page.phone.send_keys(page.u)
page.password.send_keys(page.p)
page.login.click()
page.not_now.click() # 更新cookie
time.sleep(2)
with open("./cookie.json", 'w+') as f:
f.write(str(page.get_cookies())) @verify
def __cookie_login__(self):
"""
cookie登录
"""
page.get(page.url)
with open("./cookie.json", 'r+') as f:
cookie = eval(f.read())
page.add_cookies(cookie)
time.sleep(2)
page.driver.refresh() def trigger(self):
flag = self.__cookie_login__()
flag = flag if flag else self.__account_login__()
print('登录成功状态:', flag)
return page if flag else "登录失败"
当我知道人家给我说错了后,我起初是很无语的,毕竟人家不懂技术。。。按照模拟点击这种方法,就算一张图片只用1秒,5万张图片得用5万秒,得爬到地老天荒啊!
然后我果断弃用,因为这得走接口的方式爬。
而走接口的方式有两种,一是通过requests.session,二是直接携带cookie。因为人家给我配了专门的账号,直接从浏览器上把cookie复制过来啦~
headers = {
'Content-Type': "application/x-www-form-urlencoded",
'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36",
'Referer': "https://seller.samsungapps.com/content/common/summaryContentList.as",
'Accept-Language': "zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7",
'Cookie': "SCOUTER=x7o8fo083la90t; _hjid=cd3eb857-86e9-40e5-bba4-22b101dd0552; api_auth_sub=N; sellerLocale=zh_CN; _hjTLDTest=1; SLRJSESSIONID=SLm48RCYo2WqmgbfoOt5aBjlN1zbEFw10hrQrS2WFkkXrrDaJ1E5mCL2uKcxL99E.YXBwc19kb21haW4vc2VsbGVyMTE=; iPlanetDirectoryPro=NTbL8ooVcqrDnHlwgDxcABJZuzyR4xsNS9RrqQranfGKUkPTiZR/f8kop4j6ELBPc+TaRMW88Y3hUrTscvFk5t7je/dtPLfsDoVvZZn6oau1CY4NKsdQlNlSzkj3hdp1Lj7hRz2a3Q6BENPmpVewwbT3nqyI0Pb4/ZEyHVoXTaAGDzi7NzXwM54qizpIDXc8hkXAaXhtLcvra+DyVc72Undh9U31LyYlXO53LavOIFOYgPRvA9O5b4ed6xUxxa2etz9lpMwzlIayMvrOg8hdwDE5evVwpayZjXUv1cW4lMCbJhHaVhEucux23kcOuGbBgjraYYteAQ1ndWEvm0ipsg==; gss_auth_token=V/RK27AqVE6LV2BHAoKit6cWK+EWYKc8ERpYh2Wm7ESfGLw+oU/fgZmO2w1Oo1B+A/eYhyJu/XI9EagBTF+7Jg/5vRxPyCJW9hxMvNl4dhIRrWqNCSt6IrRQb0ZWPau8xMero/9FKGi7M3lrkuOMo8aUbTnl127zw1kj0Mgbfxw=; api_auth_token=Scri8yrXRz9kYmjyPxxyDOT8lKbIfKt2TQcwPwfO14U16J0AU1vAUMsqF/LtCfg7CtYw4hQIuO6SK1mCOJKPagKvmCyt7EjBEr1TTfIhjJPWbJkJ6pey9+Sj0CWEm/EuD/rjwUPc5THhiM7vpOkpWSqJLQYDmZ6AEy5cdtsOFIZSoZmbmZnMT8CIyig0GdE8FOPNJHpXrHxTgGSRQtsgyqYiXlFGKzfmjueeMC+x02ubCLNFdhReKZ2sfBzvFc8gxPyathHVXSYN+WCW/CTheiFwTP7D8N93agwEopZeLP79UvgwOyZi1VNwNl5GGe/le8qdiv10IhWjHMbNkt4lcA==; api_server_url=cn-auth2.samsungosp.com.cn; auth_server_url=cn-auth2.samsungosp.com.cn; _hjIncludedInPageviewSample=1; _hjAbsoluteSessionInProgress=1",
}
cookie放在请求头里,我们请求头里还要添加上基本的信息,爬虫时要养好这个习惯。
二.特征提取
要爬取的是图片的id和图片的url,然后根据图片的url来进行下载,所以总共有两次爬取操作。打开谷歌浏览器页面调试台,定位到图片位置后,观察特征。
发现id都在这个td标签下面,并且id的长度为12位,能观察到的id都是以00开头,我需要的信息就在<td>标签里面;而url都是以前面的网址开头,需要的信息在img标签的src属性里面。
于是确定了它们的特征,提取出来的xpath表达式为:
img_id = s.xpath("//td[string-length(text())=12 and starts-with(text(), '00')]/text()")
img_url = s.xpath("//td/img[contains(@src,'https://img.**apps.com/content')]/@src")
翻页的特征不在地址栏,被我注意到在查询字符串里面。于是将payload写活。
payload = "statusTab=all&pageNo=" + str(page_number) + "&isOpenTheme=true&isSticker=false&hidContentType=all&serviceStatus=sale&serviceStatusSub=forSale&contentType=all&ctntId=&contentName="
三.爬取id和url
根据id和url的特征,以及实现翻页的技巧,获取所有的id和url自然不在话下。
一个一个爬取太慢,多线程走起~
import threading
from data import url, payload_pre, payload_bac, headers
import time
from lxml import etree
import requests thread_max = threading.BoundedSemaphore(10) def send_req(page):
with thread_max:
page = str(page)
payload = payload_pre + str(page) + payload_bac
response = requests.request("POST", url, data=payload, headers=headers)
text = response.text
s = etree.HTML(text)
img_id = s.xpath("//td[string-length(text())=12 and starts-with(text(), '00')]/text()")
img_url = s.xpath("//td/img[contains(@src,'https://img.samsungapps.com/content')]/@src")
a = len(img_id)
b = len(img_url)
s_ = page + " " + str(a) + " " + str(b) with open("1.txt", "a") as f:
for c, d in zip(img_id, img_url):
f.write(c + " " + d + "\n")
print("ok " + s_) if a and a == b else print("not ok " + s_ + 60 * "!") def start_work(s, e):
thread_list = []
for i in range(s, e):
thread = threading.Thread(target=send_req, args=[i])
thread.start()
thread_list.append(thread)
for thread in thread_list:
thread.join() if __name__ == '__main__':
star, end = 1, 1001
t1 = time.time()
start_work(star, end)
print("[INFO]: using time %f secend" % (time.time() - t1))
四.根据url下载
如果前面的看懂了,那么这里自然而然就懂啦~
读取url文件,就像一个一个种子(老司机你懂的),然后批量下载~
import threading
import urllib.request as ur thread_max = threading.BoundedSemaphore(10) def get_inf():
ids = []
urls = []
with open("img_1.txt", "r") as f:
while True:
con = f.readline()
if con:
ids.append(con[:12])
urls.append(con[13:-1])
else:
break
print(len(ids), len(urls))
return ids, urls def down_pic(id_, url_):
with thread_max:
try:
ur.urlretrieve(url_, "./img_1/" + id_ + ".jpg")
except Exception as e:
print(e)
print(id_, url_) def start_work(id_, url_):
thread_list = []
for i, j in zip(id_, url_):
thread = threading.Thread(target=down_pic, args=[i, j])
thread.start()
thread_list.append(thread)
for thread in thread_list:
thread.join() if __name__ == '__main__':
i_, u_ = get_inf()
start_work(i_, u_)
五.注意事项
起初没有合理控制频次,人家页面提示这个:

即便控制好了,但超过了人家的阈值,又提示了这个:

通过 threading.BoundedSemaphore() 控制多线程最大数量,危险时协调部门资源解决风控,合理爬取资源噢~
爬取精美壁纸5w张,爱了爱了的更多相关文章
- scrapy图片-爬取哈利波特壁纸
话不多说,直接开始,直接放上整个程序过程 1.创建工程和生成spiders就不用说了,会用scrapy的都知道. 2.items.py class HarryItem(scrapy.Item): # ...
- python爬取全站壁纸代码
#测试网址:https://www.ivsky.com/bizhi/ #需要安装的库:requests,bs4 #本人是个强迫症患者,为了美观添加数个print(),其并没有实际意义,若是不爽删去即可 ...
- Python 爬取必应壁纸
import re import os import requests from time import sleep headers = { "User-Agent": (&quo ...
- WebView2 通过 PuppeteerSharp 实现爬取 王者 壁纸 (案例版)
此案例是<.Net WebView2 项目,实现 嵌入 WEB 页面 Chromium内核>文的续集. 主要是针对WebView2的一些微软自己封装的不熟悉的API,有一些人已经对 Pup ...
- requests+正则表达式 爬取 妹子图
做了一个爬取妹子图某张索引页面的爬虫,主要用request和正则表达式. 感谢 崔庆才大神的 爬虫教学视频 和 gitbook: B站:https://www.bilibili.com/video/a ...
- python学习--第二天 爬取王者荣耀英雄皮肤
今天目的是爬取所有英雄皮肤 在爬取所有之前,先完成一张皮肤的爬取 打开anacond调出编译器Jupyter Notebook 打开王者荣耀官网 下拉找到位于网页右边的英雄/皮肤 点击[+更多] 进入 ...
- [python爬虫] Selenium定向爬取虎扑篮球海量精美图片
前言: 作为一名从小就看篮球的球迷,会经常逛虎扑篮球及湿乎乎等论坛,在论坛里面会存在很多精美图片,包括NBA球队.CBA明星.花边新闻.球鞋美女等等,如果一张张右键另存为的话真是手都点疼了.作为程序员 ...
- 爬取5K分辨率超清唯美壁纸
目录 爬取5K分辨率超清唯美壁纸 简介 编写思路 使用教程 演示图片 完整源代码 @ 爬取5K分辨率超清唯美壁纸 简介 壁纸的选择其实很大程度上能看出电脑主人的内心世界,有的人喜欢风景,有的人喜欢星空 ...
- 16、爬取知乎大v张佳玮的文章“标题”、“摘要”、“链接”,并存储到本地文件
爬取知乎大v张佳玮的文章“标题”.“摘要”.“链接”,并存储到本地文件 # 爬取知乎大v张佳玮的文章“标题”.“摘要”.“链接”,并存储到本地文件 # URL https://www.zhihu.co ...
- Python爬虫教程-爬取5K分辨率超清唯美壁纸源码
简介 壁纸的选择其实很大程度上能看出电脑主人的内心世界,有的人喜欢风景,有的人喜欢星空,有的人喜欢美女,有的人喜欢动物.然而,终究有一天你已经产生审美疲劳了,但你下定决定要换壁纸的时候,又发现网上的壁 ...
随机推荐
- vivo大数据日志采集Agent设计实践
作者:vivo 互联网存储技术团队- Qiu Sidi 在企业大数据体系建设过程中,数据采集是其中的首要环节.然而,当前行业内的相关开源数据采集组件,并无法满足企业大规模数据采集的需求与有效的数据采集 ...
- Dart语言简介
简单介绍Dart语言 Dart是一种针对客户优化的语言,亦可在任何平台上快速开发的应用陈旭. 目标是为多平台开发提供最高效的变成语言,并为应用程序框架搭配了领会的运行时执行平台. Dart特点 Dar ...
- 【Spark】Day05-内核解析:组件、流程、部署、运行模式、通讯架构、任务调度(Stage、task级)、两种Shuffle机制、内存管理、核心组件
一.内核概述 内核:核心组件的运行机制.任务调度.内存管理.运行原理 1.核心组件 (1)Driver驱动器节点:执行main方法,将程序转化为作业job,在executor中调度任务task,跟踪并 ...
- 直接快速下载NLTK数据
直接快速下载NLTK数据 直接下载NLTK的数据速度很慢,这里提供NLTK数据集,直接下载即可.或者选择下列百度云下载: 链接:https://pan.baidu.com/s/17ZgkoQeMosW ...
- Hexo+Gitee免费搭建静态博客
前言 这是一篇利用 Gitte Pages + hexo 搭建属于自己博客的教程,也是自己这个博客搭建好以后的第一篇文章,搭建的过程中也参考了各路大佬的文章,期间遇到了一些问题,所以写这一篇文章即是记 ...
- 【leetcode】剑指offer04二维数组查找
很巧妙地把矩阵转化为二叉搜索树(不过好像没什用) class Solution { public: bool findNumberIn2DArray(vector<vector<int&g ...
- Java基础篇——常用类
Objec类 Test t1 = new Test(); Test t2 = new Test(); //toString方法,对某个对象的字符串输出 //getClass方法,返回该对象的Class ...
- [LeetCode]对角线遍历
题目 代码 class Solution { public: vector<int> findDiagonalOrder(vector<vector<int>>&a ...
- AtCoder Beginner Contest 282 G - Similar Permutation
套路题 题意 求有多少个 \(1\) 到 \(n\) 的排列满足恰有 \(k\) 对在排列中相邻的数满足前小于后 \(2 \leq n \leq 500, 0 \leq k \leq (n - 1)\ ...
- rvm安装ruby
macOS11.1 打开终端 使用下面命令查看ruby版本 rvm list known 然后安装 rvm install 2.0.0 查看ruby版本 ruby -v 系统默认使用ruby版本 ...