组件调用:request,re,requests,threading,sys,os
实现功能:先获取到种子搜索页面的正则链接,然后通过抓取页面过滤源码标签,得到需要的信息并打印列表提供下载。
#_*_coding:utf-8_*_
from urllib import request
import re
import requests
import threading
import sys
import os
'''
This is film torrnet spider
'''
__author__ = 'demon'
class UpdateBtTorrent(object):
def __init__(self,url = 'http://www.btbtt.co/forum-index-fid-951-page-1.htm'): #构造函数,用于初始化正则以及headers等
self.domain = 'http://www.btbtt.co/'
self.page_regex = re.compile(r'<a href="(\bthread-index-fid.*htm{1}).*">')
self.bt_regex = re.compile(r'<a href="(\battach-dialog-fid.*htm{1}).*">')
self.film_name_regex = re.compile(r'"(\[BT下载\].*?)"')
self.torrent_name_regex = re.compile(r'<a .*>(.*\.torrent{1})</a>')
self.url,self.page_ursl,self.bt_urls,self.bt_download_urls = url,[],[],[]
self.headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3026.3 Safari/537.36'}
def __request_content(self,url): #请求网页返回html的源码
req = request.Request(url=url,headers=self.headers)
content = request.urlopen(req).read().decode()
return content
def get_page_urls(self): #得到电影下载页面入口中的所有电影介绍的链接
content = self.__request_content(self.url)
self.page_ursl = [self.domain+url for url in re.findall(self.page_regex,content)]
return list(set(self.page_ursl))
def get_bt_urls(self,url): #存放bt种子的方法,用于更新显示bt种子
content = self.__request_content(url)
bt_url = re.findall(self.bt_regex,content) #查找bt种子的url
if bt_url:
try:
film_name = re.findall(self.film_name_regex, content)[0].strip() #获取页面中的电影名称
except Exception as e:
pass
else:
torrent = re.sub('dialog','download',self.domain+''.join(bt_url)) #得到bt种子的下载地址
torrent_name = re.findall(self.torrent_name_regex,content)[0].strip() #得到bt种子的名称
print('电影名称:'.rjust(8),film_name)
print('BT种子下载:'.rjust(8),torrent)
print('BT种子名称:'.rjust(8),torrent_name)
print('BT详细链接:'.rjust(8),url)
print()
with open('Torrent.txt', 'a+', encoding='utf-8') as f: #保存bt种子到文本文件中
f.write('%s<--->%s<--->%s' % (film_name,torrent,torrent_name) + '\n')
f.flush()
class BtTorrent(object): #用于查找下载bt种子的方法
def __init__(self):
self.search_film_result = [] #用于存放所有film的列表
self.header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3026.3 Safari/537.36'}
def search(self,search_film): #用于搜索种子的方法
with open('Torrent.txt','r',encoding='utf-8') as f:
content = list(set(f.readlines()))
for line in content:
if re.findall(r'.*%s+.*?'%search_film,line): #正则过滤要查找的电影名称
self.search_film_result.append(line)
print('电影名称:'.rjust(8),line.split('<--->')[0])
print('种子地址:'.rjust(8),line.split('<--->')[1])
print('种子名称:'.rjust(8),line.split('<--->')[2])
return self.search_film_result
def download(self,search): #用于下载电影BT种子的方法
with open('Torrent.txt','r',encoding='utf-8') as f: #取出bt文件中的信息
content = f.readlines()
for line in content: #获取要查找的内容
if search in line:
torrent_url = line.split('<--->')[1].strip()
torrent_name = line.split('<--->')[2].strip()
data = requests.get(torrent_url,stream=True,headers=self.header)
if data.ok: #下载bt种子
print('正在准备下载电影BT种子,稍等一会我的哥~~~')
with open(torrent_name,'wb+') as f:
f.write(data.content)
print('\033[32m%s电影种子下载完毕..~~~~\033[0m'%torrent_name)
else:
print('\033[31mWTF,请求头挂了...~~~\033[0m')
class ChoiceCommand(object): #通过sys.argv传递进来的command调用不同的类方法,update,search,download...
def __init__(self,command):
self.film_page_urls = []
self.command = command #获取位置参数,update or search or download...
def update(self,start_page=1,end_page=5):
#url = 'http://www.btbtt.co/forum-index-fid-1183-page-%s.htm'
url = 'http://www.btbtt.co/forum-index-fid-951-page-%s.htm'
print('\033[32m正在初始化BT爬虫...,更新等待ing.\033[0m')
for page_num in range(start_page,end_page): #支持多页更新
self.update_tonnert = UpdateBtTorrent(url%page_num)
film_urls = self.update_tonnert.get_page_urls()
self.film_page_urls.extend(film_urls) #把每一页的电影的url都放到总的urls列表中
while self.film_page_urls: #因为bt之家有限制,不能同时开启超过10个并发,所以每次限制启动10个线程进行更新
thread = []
for film in self.film_page_urls[:10]:
t = threading.Thread(target=self.update_tonnert.get_bt_urls,args=(film,)) #更新bt种子的信息
t.start()
thread.append(t)
for th in thread:
th.join()
self.film_page_urls = self.film_page_urls[10:] #每次启动是个线程,利用列表的切片
else:
print('\033[32m请求更新的BT种子信息完毕~\033[0m')
sys.exit(0)
def search(self,film_name): #实例化搜索种子的方法
bt_torrnet = BtTorrent()
bt_torrnet.search(film_name)
def download(self,film_name): #实例化下载种子的方法
bt_torrnet = BtTorrent()
bt_torrnet.download(film_name)
if __name__ == '__main__':
if len(sys.argv) >= 3: #判断传递的参数个数
command = sys.argv[1]
choice = ChoiceCommand(command)
if hasattr(choice, command): #利用反射调取不同的类方法
if command == 'update':
update = getattr(choice, command)
start_page = int(sys.argv[2])
end_page = int(sys.argv[3])
update(start_page, end_page)
else:
if os.path.exists(os.path.join(os.path.dirname(__file__),'Torrent.txt')): #判断Torrent.txt,如果有说明有本地的bt种子库
bt = getattr(choice, command) #通过反射找到search或者download的方法
film_name = sys.argv[2]
bt(film_name) #调用对应的方法
else:
print('木有找到本地的BT种子库.\033[32m准备更新本地的种子库\033[0m ,特么的给老子消停的等一会.')
choice.update()
elif len(sys.argv) == 2 and sys.argv[1] == 'update': #不加起始页和终止页,默认更新五页
choice = ChoiceCommand('update')
choice.update()
else:
print(
'''
Low B小哥哥:
\033[31mLow B哥呀\033[0m,不是这样玩的呀.
名称:
这特么的是一个爬取小电影的bt种子
简介:
<\033[32mupdate\033[0m [更新电影的初始页,更新电影的终止页]> <\033[32msearch\033[0m电影名称> <\033[32mdownload\033[0m电影名称或者BT下载的地址>
描述:
search: 查找的电影名称
update: 更新本地BT电影库,可以加上起始、终止的页数,默认为前五页
download: 下载的电影名称或者BT种子的URL地址,默认下载查找到的第一条匹配电影
示例:
update 起始更新页 终止更新页
search 电影名称
download 电影名称
作者:
Film Torrent Spider by Demon.
''')
评论