最近没事弄了一个图床(http://788to.com),然后又比较喜欢豆瓣小组里的图片,所以就想从豆瓣小组抓取图片。云聚合只对php比较了解,但是php的多线程做爬虫的话还是比较弱的,所以就想到了用Python来做这件事情。
前篇:Chevereto free版本 使用api 上传图片 图文教程
注:云聚合是Python新手,如有不对的地方,希望大神指出。
下面将python脚本开源:
#!/usr/bin/python
# -*- coding: UTF-8 -*-
# 作者:云聚合
# 网址:http://vpsum.com/43112.html
#导入所需的库
from bs4 import BeautifulSoup
from urllib.parse import urlencode
import urllib.request,socket,re,sys,os,json,time,threading,queue
# 获取单页图片方法
def getImage(url):
# 网址
if url == '':
print('URL NULL')
sys.exit()
print(url)
print('--- Begin to Crawl Url ---')
req = urllib.request.Request(url)
res = urllib.request.urlopen(req)
data = res.read()
for link,t in set(re.findall(r'(https://img3.doubanio.com/view/group_topic/large/public/[^s]*?(jpg))', str(data))):
if link != '' :
http_status = http_get(link)
print( link + ' -> '+ http_status )
# print(link)
print('--- End to Crawl Url ---')
# 获取页面的url地址并使用getImage方法抓取图片
def getUrlList(url):
data=urllib.request.urlopen(url).read()
soup = BeautifulSoup(data, "html.parser")
tdList = soup.find_all("td",class_='title')
for i in tdList:
title = i.a.get("title")
if len(i.contents) > 1:
i_href = i.a.get('href')
getImage(i_href)
# 模拟浏览器提交数据
def http_get(url):
submit_url = 'http://788to.com/api/1/upload/?key='+urllib.parse.quote_plus('API值')+'&source='+urllib.parse.quote_plus(url)
# print(submit_url)
req = urllib.request.Request(submit_url)
try:
res = urllib.request.urlopen(req)
except urllib.error.HTTPError as e:
print(e.read())
sys.exit()
# .decode('ascii') : 将byte类型转化为字符串格式
# return res.read().decode('ascii')
data = json.loads(res.read().decode())
return str(data['status_code'])
#getUrlList('https://www.douban.com/group/meituikong/discussion?start=400')
print('群组起始地址示例:https://www.douban.com/group/meituikong/discussion?start=')
theUrl = str(input("请输入豆瓣首页地址:"))
theEnd = int(input('请输入最后一页的start数字值:'))
class jdThread(threading.Thread):
def __init__(self,index,queue):
threading.Thread.__init__(self)
self.index = index
self.queue = queue
def run(self):
while True:
time.sleep(1)
item = self.queue.get()
if item is None:
break
# print("序号:",self.index,"任务",item,"完成")
getUrlList(theUrl+str(item*25))
time.sleep(1)
self.queue.task_done() #task_done方法使得未完成的任务数量-1
if q.empty(): return
q = queue.Queue(0)
'''
初始化函数接受一个数字来作为该队列的容量,如果传递的是
一个小于等于0的数,那么默认会认为该队列的容量是无限的.
'''
for i in range(2):
jdThread(i,q).start()#两个线程同时完成任务
for i in range( int( theEnd/25) ):
q.put(i)#put方法使得未完成的任务数量+1