本帖最后由 MyModHeaven 于 2022-8-16 12:07 编辑
发现我用的 IP 都被豆瓣封了,特来把相关部分删除
-
看见一个求豆瓣电影Top 250的海报的帖子,我就尝试了一下
-
豆瓣的人机验证很迷幻,基本上下好几千张也不需要验证,有时候刚开始下几十张就需要验证。
-
代码里识别豆瓣人机验证的函数还有点问题,应该把图片保存到本地然后识别。因为很少碰到人机验证,所以这个函数现在还没改好,但是我不想下了,浪费时间,就这样吧
-
分享的海报也是只有top 200 的,后面不下了,下载链接在这个帖子里:https://www.52pojie.cn/thread-1675380-1-1.html
-
借助两个提供免费 IP 的网站
-
虽然 IP 和 UA 都是随机的,但是 cookie 就一个,不知道弄随机 IP, UA 有没有必要
-
ua 是我写的一个生成随机 ua 的文件
-
代码:
# 需要改的地方有cookies, verify(), PATH, ip,或许还有其他没提及的
import os, random
from time import sleep
from threading import Thread, active_count
import requests, ddddocr
from bs4 import BeautifulSoup
import ua
cookies = ''
def req(url, dire=True, referer='https://movie.douban.com'):
while True:
try:
# 那两个代{过}{滤}理网站不检查 referer,就将就着这样吧
r = requests.get(url, headers={'User-Agent': ua.ua, 'Cookie': cookies, 'Referer': referer}, proxies={'http': ip})
break
except:
print('————连接失败,休眠 10s。。。')
sleep(10)
continue
if dire:
sc = BeautifulSoup(r.text, 'lxml')
else:
sc = r.content
return sc
def verify(url):
# 人机验证,识别验证码
print('进行人机验证。。。。。。。。。。。。。。。。。。。。。。。。。。。。')
sorry = 'https://www.douban.com/misc/sorry'
form = req(sorry).find('form', method='POST')
img = form.img.attrs['src']
captcha_id = form.find('input', attrs={'name': 'captcha-id'}).attrs['value'] # 根据 name 属性值选择节点,不能写成 find('', name=''),会报错,要写字典里面去
content = requests.get(img, headers={'User-Agent': ua.ua, 'Cookie': cookies,})
code = ddddocr.DdddOcr(show_ad=False).classification(content)
data = {'ck': 'SWJs', 'captcha-solution': code, 'captcha-id': captcha_id, 'original-url': url}
requests.post(sorry, data=data, headers={'User-Agent': ua.ua, 'cookie': cookies})
def dl_poster(label):
posters_url = f'https://movie.douban.com/subject/{label}/photos?type=R&start=0&sortby=like&size=a&subtype=a'
soup = req(posters_url)
movie = soup.find('div', id='content').h1.string.split()[0]
if '的海报' in movie:
movie = movie[:-3]
path = part + movie # 绝对路径
if not os.path.exists(path):
os.mkdir(path)
os.chdir(path)
# 计算页数
_num = soup.find('div', id='photos_filter').find('li', class_='current').span.string[4:-1] # str
_pages = int(_num) // 30 + 1
n = 0
for page in range(_pages):
page = f'https://movie.douban.com/subject/{label}/photos?type=R&start={page*30}&sortby=like&size=a&subtype=a'
node_li = req(page).find('ul', class_='poster-col3 clearfix')( 'li')
for li in node_li:
photo, name = li.div.a.attrs['href'], ' '.join(li.get_text().split()[:-1])
if '/' in name:
name = name.replace('/', '&')
while True:
try:
jpg = req(photo).find('span', class_='update magnifier').a.attrs['href'] # 不登陆没有这个
break
except AttributeError:
verify(photo)
with open(f'{path}/{name}.jpg', 'wb') as f:
f.write(req(jpg, dire=False, referer=photo))
n += 1
print(f'【{movie}】,第 {n} 张')
print(f'已下载完毕电影 {movie},共计 {_num} 张')
for start in range(0, 250, 25):
PATH = ''
part = f'{PATH}{start}-{start+25}/' # 绝对路径
if not os.path.exists(part):
os.mkdir(part)
os.chdir(part)
url = f'https://movie.douban.com/top250?start={start}&filter='
while True:
try:
node_li = req(url).find('ol', class_='grid_view')('li')
break
except TypeError:
verify(url)
for li in node_li:
label = li.div.div.a.attrs['href'].split('/')[-2] # 每个电影的号码
Thread(target=dl_poster, args=(label,)).start()
while True:
if active_count() == 1: # 最后剩一个 MainThread
break
print(f'Top{start+25} 下载完毕')
|