• 多线程爬取豆瓣音乐


    该模块相当于爬取100个页面,打开每个页面提取自己所需要的东西

    更改的话食用方式是创建个urls列表(对应下方的get_url()函数)

     urls = ['https://music.douban.com/top250?start={}'.format(str(i)) for i in range(0,100,25)]
    

    然后就是更改下从主页获取的url链接提取方式,提取出来的url页面需要解析的数据(对应下方的get_url_music()和get_music_info()函数)

    import threading
    import datetime
    import requests
    from bs4 import BeautifulSoup
    import re
    import time
    
    # 记录开始时间
    starttime = datetime.datetime.now()
    # 创建线程锁
    lock = threading.Lock()
    # 从url列表中获取URL,这是一个同步函数
    def get_url():
        global urls # 通过这个全局变量url来获取变量
        # 获取url之前加锁
        lock.acquire()
        if len(urls) == 0:
            lock.release()
            return ""
        else:
            url = urls[0]
            del urls[0] # 提取一个url后将这个url删掉,以保障每次提取的都是最新的url
        # 完成工作释放锁
        lock.release()
        return url
    
    
    
    print(time.time())
    headers = {
        'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36',
        'cookie':'豆瓣需要自己获取cookie'
    }
    def get_url_music(url,thread_name):
        html = requests.get(url,headers=headers)
    
        soup = BeautifulSoup(html.text, 'lxml')
    
        aTags = soup.find_all("a",attrs={"class": "nbg"})
        for aTag in aTags:
            get_music_info(aTag['href'],thread_name)
    
    
    def get_music_info(url,thread_name):
        html = requests.get(url,headers=headers)
        soup = BeautifulSoup(html.text, 'lxml')
        name = soup.find (attrs={'id':'wrapper'}).h1.span.text
        author = soup.find(attrs={'id':'info'}).find('a').text
        styles = re.findall('<span class="pl">流派:</span>&nbsp;(.*?)<br />', html.text, re.S)
        if len(styles) == 0:
            style = '未知'
        else:
    
            style = styles[0].strip()
        time = re.findall('发行时间:</span>&nbsp;(.*?)<br />', html.text, re.S)[0].strip()
        publishers = re.findall('<span class="pl">出版者:</span>&nbsp;(.*?)<br />', html.text, re.S)
        if len(publishers) == 0:
            publisher = '未知'
        else:
            publisher = publishers[0].strip()
    
    
        # score = soup.find(class_='ll rating_num').text
        info = {
            'name': name,
            'author': author,
            'style': style,
            'time': time,
            'publisher': publisher,
            # 'score': score
        }
        # 输出线程名称;thread_name没定义吧,这个是函数中的参数;这sprint就是在函数中
        print(thread_name, info) # 这一句话也没执行
    # 这是一个线程类
    class SpiderThread (threading.Thread):   #继承父类threading.Thread
    
        def __init__(self,name):
            threading.Thread.__init__(self)
            # name是线程名
            self.name = name
        def run(self): # 这一句没有运行
            # 多线程的话更改下这里
            while True:
                url = get_url()
                if url != "":
                    # 线程一旦运行就会从列表中不断获取URL,知道列表为空
                    get_url_music(url,self.name)
                else:
                    break
    
    
    if __name__ == '__main__':
        url_index = 0
        urls = ['https://music.douban.com/top250?start={}'.format(str(i)) for i in range(0,100,25)]
        print(len(urls))
        # 创建4个新线程
        thread1 = SpiderThread('thread1') # 这里为啥可以传字符串进去;init中定义了就是线程的名字
        thread2 = SpiderThread('thread2')
        thread3 = SpiderThread('thread3')
        thread4 = SpiderThread('thread4')
    
        # 开启4个线程
        thread1.start()
        thread2.start()
        thread3.start()
        thread4.start()
        # 等4个线程结束,才会退出爬虫
        thread1.join()
        thread2.join()
        thread3.join()
        thread4.join()
        print("退出爬虫")
        endtime = datetime.datetime.now()
        print('需要时间:',(endtime - starttime).seconds,'秒')
    
    
    
  • 相关阅读:
    Session的使用与Session的生命周期
    Long-Polling, Websockets, SSE(Server-Sent Event), WebRTC 之间的区别与使用
    十九、详述 IntelliJ IDEA 之 添加 jar 包
    十八、IntelliJ IDEA 常用快捷键 之 Windows 版
    十七、IntelliJ IDEA 中的 Maven 项目初体验及搭建 Spring MVC 框架
    十六、详述 IntelliJ IDEA 创建 Maven 项目及设置 java 源目录的方法
    十五、详述 IntelliJ IDEA 插件的安装及使用方法
    十四、详述 IntelliJ IDEA 提交代码前的 Code Analysis 机制
    十三、IntelliJ IDEA 中的版本控制介绍(下)
    十二、IntelliJ IDEA 中的版本控制介绍(中)
  • 原文地址:https://www.cnblogs.com/wkhzwmr/p/15693789.html
Copyright © 2020-2023  润新知