代码有什么问题

代码有什么问题

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


def handle_request(url):
    """
    处理request函数
    :param url:
    :return:
    """
    headers = {
        'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36 Edg/95.0.1020.44'
    }
    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
        """
        #页码数据实例化
        item_html = etree.HTML(content)
        #解析所有详情页URL
        detail_urls= item_html.xpath("//a[@class='thumbnail']/@href")
        for detail_url in detail_urls:
            #将详情页放入队列中
            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():
                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):
    def __init__(self,thread_name, data_queue, detail_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))
        #需要不断从页码QUEUE里面获取URL, 并且发送请求,要看self.page_queue是否为空
        try:
            #从detail_queue获取90个详情页的URL
            while not self.detail_queue.empty():
                detail_url = self.detail_queue.get(block=False)
                detail_response = handle_request(url=detail_url)
                if detail_response:
                #解析30条详情页的URL
                    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(DetailSpider, self).__init__()
        self.thread_name= thread_name
        self.data_queue = data_queue
        self.mongo = mongo
        self.lock = lock

    def _join_list(self,item):
        return ''.join(item)

    def parse(self, data):
        """
        解析data_queue数据
        :param data:data_queue.get()
        :return:pymongo
        """
        #实例化HTML数据
        html = etree.HTML(data)
        info = {
            '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):
        #实际发送请求,请求页码URL
        print('{}启动'.format(self.thread_name))
        #需要不断从页码QUEUE里面获取URL, 并且发送请求,要看self.page_queue是否为空
        try:
            #从data_queue获取90个详情页的URL
            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()
    for i in range(1, 4):
        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 = []
    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()

    # print(data_queue.qsize())
    #第三个爬虫
    #使用lock,向mongo插入数据
    lock = threading.Lock()

    client= pymongo.MongoClient(host='127.0.0.1',port=1112)
    mydb = client['db_movie']
    mycollection = mydb['movie_info']

    data_parse_threadname_list = ['数据线程1号', '数据线程2号', '数据线程3号', '数据线程4号', '数据线程5号']
    data_parse_list = []
    for thread_name in data_parse_threadname_list:
        thread = DetailSpider(thread_name, data_queue, data_queue)
        thread.start()
        data_parse_list.append(thread)

    # 查看当前detail_queue里面数据状态
    while not data_queue.empty():
        pass
    for thread in data_parse_list:
        if thread.is_alive():
            thread.join()

if __name__=='__main__':
    main()

列表线程1号启动

列表线程2号启动

列表线程3号启动

列表线程3号结束

列表线程1号结束

列表线程2号结束

详情线程1号启动

详情线程1号结束

详情线程2号启动

详情线程2号结束

详情线程3号启动

详情线程3号结束

详情线程4号启动

详情线程4号结束

详情线程5号启动

详情线程5号结束

循环到这之后没有了,一直循环什么问题


下载视频          

正在回答 回答被采纳积分+1

登陆购买课程后可参与讨论,去登陆

1回答
好帮手慕美 2021-11-14 18:09:47

同学,你好!

1、__init__()中定义参数的顺序与创建实例时传入的参数顺序应一致

https://img1.sycdn.imooc.com//climg/6190df4a092a787013080407.jpg

https://img1.sycdn.imooc.com//climg/6190df68090d55e812950232.jpg

2、调用父类时应是当前子类的名字

https://img1.sycdn.imooc.com//climg/6190dfac0983097412570454.jpg

3、第三个掉虫中应调用DataParse()

https://img1.sycdn.imooc.com//climg/6190dfd309b32aff13730297.jpg

祝学习愉快!

  • 提问者 慕妹2590417 #1

    run error:127.0.0.1:1112: [WinError 10061] 由于目标计算机积极拒绝,无法连接。, Timeout: 30s, Topology Description: <TopologyDescription id: 6190e88399b15aefd1b849ac, topology_type: Single, servers: [<ServerDescription ('127.0.0.1', 1112) server_type: Unknown, rtt: None, error=AutoReconnect('127.0.0.1:1112: [WinError 10061] 由于目标计算机积极拒绝,无法连接。')

    为什么连不上MongoDB

    下载视频          
    2021-11-14 19:37:10
  • 好帮手慕美 回复 提问者 慕妹2590417 #2

    同学,你好!同学可以看下连接的数据库服务是否开启。课程中连接的是虚拟机中的MongoDB,虚拟机是需要开启的。同学也可以连接本地的MongoDB数据库

    祝学习愉快!

    2021-11-15 09:48:21
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师