首页 > 其他分享 >movie

movie

时间:2024-05-08 23:22:07浏览次数:17  
标签:name thread movie self detail queue page

import requests
import pymongo
from queue import Queue
from lxml import etree
import threading


def handle_request(url):
"""
处理request函数
:param url:
:return: response.text
"""
# 自定义请求头
headers = {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36",
}
# 发送请求,有代理信息,就将代理添加进来
response = requests.get(url=url, headers=headers, timeout=(5, 5), proxies=None)
if response.status_code == 200 and response:
return response.text


class PageSpider(threading.Thread):
"""
页码URL请求多线程爬虫类
"""

def __init__(self, thread_name, page_queue, detail_queue):
super(PageSpider, self).__init__()
self.thread_name = thread_name
self.detail_queue = detail_queue
self.page_queue = page_queue

def parse_detail_url(self, content):
"""
处理page_url页面的返回数据,解析详情页的URL
:param content:page_response.text
:return: detail_url, self.detail_queue
"""
# 页码返回数据HTML实例化
item_html = etree.HTML(content)
# 解析出所有的详情页URL
detail_urls = item_html.xpath("//a[@class='thumbnail']/@href")
for detail_url in detail_urls:
# 将详情页的URL放入detail_queue
self.detail_queue.put(detail_url)

def run(self):
# 实际发送请求,请求页码URL
print("{}启动".format(self.thread_name))
# 需要不断的从页码QUEUE里面获取URL,并且发送请求,要看self.page_queue是否为空
try:
while not self.page_queue.empty():
# 从QUEUE中获取数据,并设置为非阻塞状态
page_url = self.page_queue.get(block=False)
# 请求页码链接
page_response = handle_request(url=page_url)
if page_response:
# 解析30条详情页的URL
self.parse_detail_url(content=page_response)
except Exception as e:
print("{} run error:{}".format(self.thread_name, e))
print("{}结束".format(self.thread_name))


class DetailSpider(threading.Thread):
"""
详情页URL请求多线程爬虫类
"""

def __init__(self, thread_name, detail_queue, data_queue):
super(DetailSpider, self).__init__()
self.thread_name = thread_name
self.detail_queue = detail_queue
self.data_queue = data_queue

def run(self):
# 实际发送请求,请求页码URL
print("{}启动".format(self.thread_name))
try:
# 从detail queue里不断的获取这90个详情页的URL
while not self.detail_queue.empty():
# 从QUEUE中获取数据,并设置为非阻塞状态
detail_url = self.detail_queue.get(block=False)
# 请求页码链接
detail_response = handle_request(url=detail_url)
if detail_response:
# 请求回来的详情页的数据放入到dataqueue里面去
self.data_queue.put(detail_response)
except Exception as e:
print("{} run error:{}".format(self.thread_name, e))
print("{}结束".format(self.thread_name))


class DataParse(threading.Thread):
"""
详情页数据处理类
"""

def __init__(self, thread_name, data_queue, mongo, lock):
super(DataParse, self).__init__()
self.thread_name = thread_name
self.data_queue = data_queue
self.mongo = mongo
self.lock = lock

def _join_list(self, item):
"""
处理列表的
:param item:
:return:
"""
return "".join(item)

def parse(self, data):
"""
解析data_queue里面的数据
:param data: data_queue.get()
:return: pymongo
"""
# 实例化程HTML数据
html = etree.HTML(data)
info = {
# xpath解析出来之后是一个列表
"title": self._join_list(html.xpath("//div[@class='page-header']/h1/text()")),
"update_time": self._join_list(html.xpath("//div[@class='panel-body']/p[1]/text()")),
"type": self._join_list(html.xpath("//div[@class='panel-body']/p[2]/text()")),
"starring": self._join_list(html.xpath("//div[@class='panel-body']/p[3]/text()")),
"desc": self._join_list(html.xpath("//div[@class='panel-body']/p[4]/text()")),
"download_url": self._join_list(html.xpath("//div[@class='panel-body']/p[5]/text()")),
"source_url": self._join_list(html.xpath("//div[@class='panel-body']/p[6]/a/text()"))
}
# 由于是多线程并发插入数据,因此使用lock来进行控制
with self.lock:
self.mongo.insert_one(info)

def run(self):
print("{}启动".format(self.thread_name))
try:
# 从dataqueue里不断的获取这90个详情页的数据
while not self.data_queue.empty():
# 取数据
detail_info = self.data_queue.get(block=False)
# xpath解析网页数据
self.parse(detail_info)
except Exception as e:
print("{} run error:{}".format(self.thread_name, e))
print("{}结束".format(self.thread_name))


def main():
# 页码队列
page_queue = Queue()
# 仅发送3页数据,用于测试
for i in range(1, 172):
page_url = "http://movie.54php.cn/movie/?&p={}".format(i)
page_queue.put(page_url)
# 电影详情页URL队列
detail_queue = Queue()
# 详情页数据队列
data_queue = Queue()


# 第一个爬虫
page_spider_threadname_list = ["列表页采集线程1号", "列表页采集线程2号", "列表页采集线程3号"]
page_spider_list = []
for thread_name in page_spider_threadname_list:
thread = PageSpider(thread_name, page_queue, detail_queue)
# 启动线程
thread.start()
page_spider_list.append(thread)

# 查看当前page_queue里面数据状态
while not page_queue.empty():
# 有数据的时候什么都不干
pass
# 释放资源
for thread in page_spider_list:
if thread.is_alive():
thread.join()

# 第二个爬虫
detail_spider_threadname_list = ["详情页采集线程1号", "详情页采集线程2号", "详情页采集线程3号", "详情页采集线程4号", "详情页采集线程5号"]
detail_spider_list = []
# 启动了5个线程去抓取详情页的信息
for thread_name in detail_spider_threadname_list:
thread = DetailSpider(thread_name, detail_queue, data_queue)
# 启动线程
thread.start()
detail_spider_list.append(thread)

# 查看当前detail_queue里面数据状态
while not detail_queue.empty():
# 有数据的时候什么都不干
pass
# 释放资源
for thread in detail_spider_list:
if thread.is_alive():
thread.join()
# # 在这里能看到90能看到90条数据
# print(data_queue.qsize())

# 第三个,没有发送请求,解析数据
# 使用Lock,要向mongo插入数据
lock = threading.Lock()

# 数据存入mongo,1\看虚拟机端口转发是否配置,2\mongo服务是否启动3\防火墙是否关闭,4\查看mongo的配置文件
myclient = pymongo.MongoClient("mongodb://127.0.0.1:1112")
mydb = myclient["db_movie"]
mycollection = mydb["movie_info"]

# 启动多线程,处理数据
data_parse_threadname_list = ["数据处理线程1号", "数据处理线程2号", "数据处理线程3号", "数据处理线程4号", "数据处理线程5号"]
data_parse_list = []
# 启动了5个线程处理详情页的信息
for thread_name in data_parse_threadname_list:
thread = DataParse(thread_name, data_queue, mycollection, lock)
# 启动线程
thread.start()
data_parse_list.append(thread)

# 查看当前data_queue里面数据状态
while not data_queue.empty():
# 有数据的时候什么都不干
pass
# 释放资源
for thread in data_parse_list:
if thread.is_alive():
thread.join()


if __name__ == '__main__':
main()

标签:name,thread,movie,self,detail,queue,page
From: https://www.cnblogs.com/lqdby/p/18181143

相关文章

  • MoviePy:视频编辑库
    什么是MoviePy?MoviePy是一个用Python编写的视频编辑库,它可以处理视频剪辑、合成、处理等各种任务。它背后的魔法来自于两个强大的工具:FFmpeg,一个处理多媒体数据的开源库;以及NumPy,一个强大的科学计算库。MoviePy让你可以用几行代码完成从视频剪辑到色彩调整的所有工作。为什么选......
  • My favourite movie
    Myfavouritemovieis"Flipped",directedbyRobReiner.Themoviehasbeenwidelypraisedforitswarmnarrativeanddelicatedepictionofteenages'growth.Hereisananalysisofthefilm'sdetails:Music:Thefilmscorewascompose......
  • moviepy音视频剪辑-音视频的加载和输出
    一、概述在本地进行音视频处理时,首先要从视频文件进行音视频加载,最后要将处理结果输出到文件。本节介绍moviepy的音视频的加载和输出方法。二、视频加载2.1、视频加载方法要从视频文件中加载视频非常简单,使用VideoFileClip类的构造方法即可完成加载。其构造方法语法如下:__init__......
  • 【python】只需一段代码,剪辑一个视频——Moviepy详解
    http://www.shanhubei.com/archives/2757.html前言知道吗,用moviepy一行代码就能够快速剪辑视频中某个区间的片段:clip=VideoFileClip(“videoplayback.mp4”).subclip(50,60)这一段代码,能够在3秒内将videoplayback.mp4的50秒-60秒的视频片段提取出来,非常方便。仅如此,movie......
  • CF1862E Kolya and Movie Theatre 题解
    先注意到我们娱乐值损耗的多少只与最后一场电影有关系,所以假设最后一场电影看的下标为\(k\),那么最后就要减去\(d\timesk\)。得出这个性质之后开个小根堆反悔贪心即可,首先\(a_i<0\)的没必要考虑,对于\(a_i>0\)的,如果还没到\(m\)场电影,我们就直接往里塞就可以,如果到了,我们......
  • E. Kolya and Movie Theatre
    观察一下可以发现,d产生的消耗只与最后一次电影的观看位置有关。设1<=i<=n,那么由d产生的消耗就是i*d。同时能从1~i中取得的回报是这段区间里最大的m个正数。用一个优先队列维护最大的m个正数,用val维护d产生的消耗与最大的m个正数产生的回报,记录所有位置的最大值,最后判断一......
  • 改造版:moviepy使用ffmpeg按照长度分割mp4,根据源文件命名,及时关闭文件避免异常
    importos#导入os模块,用于处理文件和目录操作importsubprocess#导入subprocess模块,用于在新的进程中执行子程序importtime#导入time模块,用于处理时间相关操作importrandomfrommoviepy.editorimportVideoFileClip#从moviepy.editor模块导入VideoFileCl......
  • E. Kolya and Movie Theatre
    E.KolyaandMovieTheatreRecently,Kolyafoundoutthatanewmovietheatreisgoingtobeopenedinhiscitysoon,whichwillshowanewmovieeverydayfor$n$days.So,onthedaywiththenumber$1\lei\len$,themovietheatrewillshowthepre......
  • movielens数据集分析python
    Movielens数据集分析Python实现概述本文将介绍如何使用Python对Movielens数据集进行分析。Movielens是一个常用的电影评分数据集,包含了用户对电影的评分、电影信息和用户信息等数据。通过对这个数据集的分析,我们可以探索用户对电影的评分情况,了解用户和电影的特征,并进一步进行推......
  • MATLAB模糊C均值聚类FCM改进的推荐系统协同过滤算法分析MovieLens电影数据集
    全文链接:http://tecdat.cn/?p=32594原文出处:拓端数据部落公众号在当今信息爆炸的时代,电影作为人们生活中不可或缺的娱乐方式,受到了越来越多的关注。而为了让观众能够更好地选择适合自己口味的电影,推荐系统成为了一个备受关注的研究领域。协同过滤算法是其中一种被广泛使用的方法......