目标网站:https://www.igdcc.com/4Kmeinv
目标产出:抓取第一页中的所有图片。
网站分析:无任何反爬策略,适合新手熟悉相关包的使用。
导入第三方包、设置线程数
import os
import sys
import random
import time
import requests
import threading
from lxml import etree
real_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..')
max_connections = 10
pool_sema = threading.BoundedSemaphore(max_connections)
抓取网站第一页数据
def get_text(url):
for i in range(3):
try:
resp = requests.get(url, timeout=10)
if resp.status_code != 200:
time.sleep(5)
continue
return resp.text
except Exception as e:
time.sleep(5)
print('抓取失败:', url)
获取图片的url
def get_image_urls(text):
if not text:
return
root = etree.HTML(text)
a_lts = root.xpath('//*/div[@class="mt15 clearfix pic-auto pic-list"]/a')
ret = []
for a in a_lts:
urls = a.xpath('.//@data-original')
if urls:
ret.append(urls[0])
return ret
保存图片(增加线程锁)
def get_content(url):
for i in range(3):
try:
resp = requests.get(url, timeout=10)
if resp.status_code != 200:
time.sleep(5)
continue
return resp.content
except Exception as e:
time.sleep(5)
def save_image(output_file, image_url):
pool_sema.acquire()
content = get_content(image_url)
if not content:
return
with open(output_file, 'wb') as fw:
fw.write(content)
time.sleep(random.random())
pool_sema.release()
主函数
def start():
url = 'https://www.igdcc.com/4Kmeinv/'
# output_dir = os.path.join(real_path, 'data')
output_dir = os.path.join(os.path.dirname(sys.argv[0]), 'data')
if not os.path.exists(output_dir):
cmd = 'mkdir %s' % output_dir
cmd = cmd.replace('/', '\\')
os.system(cmd)
print('数据目录创建成功:data')
print('只会抓取第一页哦>_<')
text = get_text(url)
image_urls = get_image_urls(text)
print('开始抓取图片~')
thread_list = []
for i in range(len(image_urls)):
output_file = os.path.join(output_dir, str(i) + '.png')
image_url = image_urls[i]
th = threading.Thread(target=save_image, args=(output_file, image_url))
thread_list.append(th)
for th in thread_list:
th.start()
for th in thread_list:
th.join()
打包成一个exe文件
1、安装pyinstaller:pip install -i http://mirrors.aliyun.com/pypi/simple pyinstaller
2、打开控制台,进入项目中,执行:pyinstaller -F .\src\spider.py -n app的名称
注意:指定你的主文件即可,打包中会自己去找到相关的文件
这个时候恭喜你,已经成功了。
3、代码中,关于真实路径以及最后的输出目录,我也是测试了一下,才发现最后输出的目录用当前的路径来做最好,而真实路径的用途主要用在导入自己写的包的时候。
4、你是windows打包出来的就只能是windows用,mac电脑就只能是mac用。
5、本次目标网站主要用学习Python中的相关技术,各位客官可以选择其他网站,修改get_image_urls函数中图片获取的方式就可以达到目的。
6、最后产出文件会和exe文件同一目录下的data目录中。
7、最后的exe文件,存在权限问题,如果在其他app的目录中,比如微信,执行会失败。将文件拉取到桌面可以正常运行。
更进一步
1、多线程跑失败的url怎么处理?怎么实现分布式抓取?多线程日志输出?
可以使用队列来完成,避免资源竞争
2、如果有反爬策略怎么处理?
需要根据具体网站来分析,通过放慢频率、js逆向、第三方插件(滑块、验证码等)、selenium等来完成验证。
无论任何时候,我们都应该在确保别人服务器正常的情况下获取数据,争取做一个有素质的客人。