【保姆级爬虫】微博关键词搜索并获取博文和评论内容(python+selenium+chorme)

微博爬虫记录

写这个主要是为了防止自己忘记以及之后的组内工作交接,至于代码美不美观,写的好不好,统统不考虑,我只能说,能跑就不错了,上学压根没学过python好吧,基本上是crtl+c&ctrl+v丝滑小连招教会了我一点。

写的很简单,认真看完就会用了

文中筛选元素用到的一些筛选元素的正则匹配、beautifulsoup,css等相关方法我也不太懂,现学现用呗,还是那句话,能跑就行。

配置简介
python3.6、selenium3.13.0,chorme以及与chorme版本对应的chormedriver
(selenium在4版本后的一些语句会需要修改,网上一大把自己查)

目录

1、启动程序控制的chorme,手动登录微博
2、在微博进行关键词的检索
3、微博的发布信息获取
4、保存数据
5、实现自动翻页
6、微博的评论信息获取

1、先启动一个由程序控制的chorme

(1)win+R,输入cmd打开命令行,输入代码进入chorme的安装位置

C:\Program Files\Google\Chrome\Application

(2)分配chorme的端口号(我这里设置的是9527)和数据目录(我这里是在D:\selenium\AutomationProfile)

chrome.exe --remote-debugging-port=9527 --user-data-dir="D:\selenium\AutomationProfile"

每次执行(1)(2)两行命令就能打开同一个chorme了,建议放在程序解析的最上方,这样浏览器关闭后下次可以通过命令行快速打开
(3)浏览器已经打开了,登录一下自己的微博
(4)链接一下程序和浏览器

# 这部分代码我直接扔在了所有函数之前,搞全局
# 把chormedriver的路径写到这里
chromedriver_path= "D:/Users/16653/AppData/Local/Programs/Python/Python36/chromedriver.exe"
option = ChromeOptions()
option.add_experimental_option("debuggerAddress", "127.0.0.1:9527")
web = webdriver.Chrome(executable_path=chromedriver_path, options=option)
web.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
    "source": """
    Object.defineProperty(navigator, 'webdriver', {
      get: () => undefined
    })
  """
})
web.implicitly_wait(10)# 等待网页的加载时间

2、进行关键词的检索

从这里开始写函数的主体,自己搞个函数名把这些代码放进去
关键词搜索的链接如下:

https://s.weibo.com/weibo?q=这里填关键词&Refer=index

搜索页面翻页直接在后面加一个page=页码,如第二页

https://s.weibo.com/weibo?q=这里填关键词&Refer=index&page=2

selenium获取初步搜索结果

web.get(url) # url就是搜索的链接
html = web.page_source
print (html) # 输出当前程序获取到的网页信息,用于检查网页是否正常获取

在浏览器里点击右键选择检查,在浏览器里面可以用检查页面左上角的框框箭头符号方便得在左边选择图案或者文字,然后实时在右边看到这个被选择的要素在哪个标签

可以发现每个博文都在action-type="feed_list_item"的div标签下(结合下图左右蓝色部分理解,标签就是一个<>包含的东西)这是一个很重要的地方,学会用浏览器的这个功能选取自己需要的信息在哪个标签里面,下面所有获取信息的代码几乎都是基于此

在这里插入图片描述
那我们可以通过beautifulsoup的findAll函数把所有这些标签的内容选择出来放进list(其他标签下提取信息也适用这个函数哦,只需要对应修改div,action-type,feed_list_item就行)
如果只想要找到的第一个div标签下的信息就用find函数,而不是findAll

soup = bs(html, 'html.parser')
list = soup.findAll("div", {'action-type': "feed_list_item"})

3、解析多种数据

(1)获取博文的文本内容,微博的文章字数太长会收起来,为了文本内容获取完整必须先将所有文本展开。
在这里插入图片描述

 	web_object = {}
    html = web.page_source
    # 获取这一网页的所有未展开的文章的展开按钮
    button_list = web.find_elements_by_css_selector('a[action-type="fl_unfold"]') #点击所有展开
    # 在for循环里面每个都点击展开
    for bt in button_list:
        try :
            bt.click()
        except Exception as e:
            print(e.args)

    # html转beautifulsoup格式
    soup = bs(html, 'html.parser')
    # 已经展开了,开始正常获取这一页的微博列表list
    list = soup.findAll("div", {'action-type': "feed_list_item"})
    for i in list:
        # 获取微博的文本信息,strip用于跳过字符前面的空白
        txt = i.findAll("p", {'class':"txt"})[-1].get_text().strip()
        print(txt) # 输出获得的内容
        web_object['text'] = txt

(2)获取微博的mid

    mid = i.get("mid")
    print("mid",mid)
    web_object['mid'] = mid

(3)获取发布者的昵称

  user_name = i.find("a", {'class': "name"}).get_text()#名字放在class为name的a标签里面
  print("昵称", user_name)
  web_object['user_name'] = user_name

(4)获取时间

        i = i.find("div",{'class':"card"})
        itime = i.find("div", {'class': "from"})
        uptime = itime.find("a").get_text().strip()
        print("发布时间:", uptime)
        web_object['date'] = uptime

(5)点赞、评论、转发的人数

		cardact = i.find("div", {'class': "card-act"})
        repost_num = cardact.findAll("li")[0].get_text().strip()
        if repost_num =="转发":
            repost_num = 0
        print("转发人数:", repost_num)
        web_object['repost_num'] = repost_num

        comment_num = cardact.findAll("li")[1].get_text().strip()
        if comment_num == "评论":
            comment_num = 0
        print("评论人数:", comment_num)
        web_object['comment_num'] = comment_num

        like_num = cardact.findAll("li")[2].get_text().strip()
        if like_num == "赞":
            like_num =0
        print("点赞人数:", like_num)
        web_object['like_num'] = like_num

(6)获取更多关于微博博主的信息
需要先从微博的搜索页面跳转到用户的界面,获取完信息后需要再跳转回来

 # 控制跳转
 user_link=i.find("a").get("href")
 print("用户主页:", user_link)
 web_object['user_link'] = user_link
 # 拼出用户的主页链接user_url
 user_url = "'" + "https:" + user_link+ "'"
 js = "window.open(" + user_url + ");"
 web.execute_script(js)
 time.sleep(random.randint(2, 5))
 # 切换到新窗口
 # 获得打开的第一个窗口句柄
 window_1 = web.current_window_handle
 # 获得打开的所有的窗口句柄
 windows = web.window_handles
 # 切换到最新的窗口
 for current_window in windows:
     if current_window != window_1:
          web.switch_to.window(current_window)

  html = web.page_source
  soup = bs(html, 'html.parser')
  print("切换到用户主页")

(7)获取用户类型(红V,蓝V,黄V等)
同样的,先获取这个类型所在的网页标签,然后得到具体内容,如果没有红V,蓝V,黄V则程序执行异常,通过try语句抓取异常,将用户类型设置为普通用户

        try:
            typehtml = soup.find("div",{'class':"woo-avatar-main woo-avatar-hover ProfileHeader_avatar2_1gEyo"})
            user_type = typehtml.find("span").get("title")
            web_object['user_type'] = user_type
            print("用户类型", user_type)
        except AttributeError as e:
            web_object['user_type'] = '普通用户'
            print("用户类型:", '普通用户')

(8)获取用户性别

        genderhtml = soup.find("div",{'class': "woo-box-flex woo-box-alignCenter ProfileHeader_h3_2nhjc"})
        gender = genderhtml.find("span").get("title").strip()
        print("用户性别:", gender)
        web_object['gender'] = gender

(9)获取用户的粉丝关注人数

fanshtml = soup.find("div",{'class': "woo-box-flex woo-box-alignCenter ProfileHeader_h4_gcwJi"})
followers = fanshtml.findAll("a")[0].get_text().strip('粉丝')
followers =followers[3:]
follow = fanshtml.findAll("a")[1].get_text().strip('关注')
follow = follow[3:]
print("粉丝数量:",followers,"关注人数:",follow)
web_object['follow'] = follow
web_object['followers'] = followers

(10)获取用户的ip以及年龄

地址有两种,一种直接在用户界面写ip属地后面接ip地址,另一种是地点的小图标后接ip地址,所以需要先判断是不是能用第一种拿到ip,不行就用第二种,都不行就是没有ip

浏览器检查网页可以发现,展开后的一条条的信息标签都是一样的,不好区分,这里采用获取文本信息后进行关键词的监测来从中获取ip属地和出生日期

在这里插入图片描述

       # 点击展开用户主页信息
        button = web.find_element_by_xpath('//*[@id="app"]/div[2]/div[2]/div[2]/main/div/div/div[2]/div[1]/div[1]/div[3]/div/div/div[2]')
        button.click()
        html = web.page_source
        soup = bs(html, 'html.parser')
        ipflag = 0# 为1时表示已经获取ip信息
        infohtml = soup.findAll("div",{'class': "woo-box-item-flex ProfileHeader_con3_Bg19p"})
        for info in infohtml:
            str1 = str(info.get_text()).strip()
            print(str1)
            try:
                if (keywords_check('加入微博', str1)):#日期后面跟一个“加入微博”,排除
                    print("加入微博时间,不是生日")
                else:	# 正则匹配日期格式
                    result = re.findall("\d{4}[-|.|/]?\d{2}[-|.|/]?\d{2}", str1)
                    if(result):
                        print("生日", result[0])
                        age = age_calc(result[0], '2024-01-06')#网上搜的一个生日计算的方法
                        print(age)
                        web_object['age'] = age
            except TypeError as e:
                print('')
            if (keywords_check('IP属地', str1)):# 检查用户主页是否有ip属地这种格式的ip
                ipflag = 1	# 有的话标记为1,表示已经拿到ip
                ip = str1[5:] # 将(ip属地:)五个字符去掉,保留后面的地址
                print("地址", ip)

        if ipflag == 0: #如果前面没找到ip属地,则找ip图标来判断
            try:
                iphtml = soup.find("div",{'class':"ProfileHeader_box3_2R7tq"})
                ip = iphtml.find("i",{'class':"woo-font woo-font--proPlace"}).parent.parent.get_text()
                print("ip:", ip)
            except AttributeError as e:
                    print("该用户没有ip信息")

网上随便找的根据日期计算生日的方法

def age_calc(birth_date, end_date):
    # 将日期转化为datetime类型
    birth_date = datetime.strptime(birth_date, '%Y-%m-%d')
    end_date = datetime.strptime(end_date, '%Y-%m-%d')
    # 分别计算年月日
    day_diff = end_date.day - birth_date.day
    month_diff = end_date.month - birth_date.month
    year_diff = end_date.year - birth_date.year

    if day_diff >= 0:
        if month_diff >= 0:
            years_old = year_diff
        else:
            years_old = year_diff - 1
    else:
        if month_diff >= 1:
            years_old = year_diff
        else:
            years_old = year_diff - 1

    return years_old

检查关键词的方法,keywords是要找的关键词,text是全部文本

def keywords_check(keyswords, text):
  keyswords
  result = re.search(keyswords, text)
  return result

4、保存数据

#  保存数据
def save_data(web_data,filename):
    fieldnames = ['mid', 'text', 'date', 'user_name', 'gender', 'follow', 'followers','age','ip','user_type','user_link','repost_num','comment_num','like_num']
    with open(filename, mode='a', newline='', encoding='utf-8-sig') as f:
        writer = csv.DictWriter(f, fieldnames=fieldnames)
        # 判断表格内容是否为空,如果为空就添加表头
        if not os.path.getsize(filename):
            writer.writeheader()  # 写入表头
        writer.writerows([web_data])

如此一来,一个微博内容以及发布者的信息获取就完成了,我们保存数据后再次切换网页到搜索页面,在此之后就是继续对前文提到的微博列表list里面的下一个微博进行上述处理,文章3.1写到的for已经帮助我们进行了循环功能,所以这下面的代码放在for循环里面就可以了

        save_data(web_object, filename)# 保存
        web.close()
        # 回到主页面
        web.switch_to.window(web.window_handles[0])

5、搜索结果翻页

前面我们只实现了一页网页的数据,下面实现翻页

    page_count = 50  #  总页数设置
    for page in range(page_count):
        print('开始获取第%d页的搜索结果'%(page+1))
        temp =str(page+1)
        url ='https://s.weibo.com/weibo?q=关键词&Refer=index&page=%s'%(temp)
        filename = os.getcwd()+'/data/微博/搜索结果.csv' # 没有目录就新建一个目录
        start_crawler(url, filename)

将以上内容串起来
下面的start_crawler函数就是爬虫的主体,也就是写
web.get(url)
print(“=开始了开始啦====”)
html = web.page_source
等等等上述代码

if __name__ == '__main__':
    # 测试用的url链接
    page_count = 50  #  总页数设置
    for page in range(page_count):# for循环进行翻页
        print('开始获取第%d页的搜索结果'%(page+1))
        temp =str(page+1)
        url ='https://s.weibo.com/weibo?q=关键词&Refer=index&page=%s'%(temp)
        filename = os.getcwd()+'/data/关键词.csv' # 没有目录就先新建一个目录
        start_crawler(url, filename)

6、微博的评论信息获取

这是另一个python文件了,这里用的评论链接获取的网页和前面的网页不同,是json格式的数据,解析数据时用到的方法不同,详情可以自行搜索

6.1先看主函数
read_mid读取目标微博的mid号列表,然后用mid拼成每条微博评论所在的链接url,通过start_crawler爬取每条微博的所有评论

if __name__ == '__main__':
    # 测试用的url链接
    filename = r"放你上面步骤爬取得到的的文件路径"
    write_path = r"随意路径\微博评论.csv"
    midlist = read_mid(filename)
    count = 1
    for i in midlist:
         if count >9:
            print("====================第%d篇微博==============="%count)
            mid = i[3:]
            url = 'https://m.weibo.cn/comments/hotflow?id=%s&mid=%s'%(mid,mid)
            print(url)
            start_crawler(url, write_path,i)# 也存一下评论属于哪一条微博
         count = count+1

6.2 read_mid函数

def read_mid(filename):
    data = pd.read_csv(filepath_or_buffer=filename, encoding="utf-8",converters={"mid":str})
    return data['mid'][data['comment_num']>=10]  # 获取评论数不少于10的微博mid

6.3 start_crawler函数
涉及到评论翻页的问题,评论翻页用max_id来标记(微博自己设置的),为0时翻页完毕
将获取的网页数据识别成json处理

def start_crawler(url,filename,mid):
    comment_url = url
    max_id = 1 # 评论翻页的位置
    page = 1
    while (max_id):
        if max_id == 0:
            break
        elif max_id != 1:
            url = comment_url+'&max_id='+str(max_id)
            print(url)
        print("======================第%d页===================="%page)
        web.get(url)
        time.sleep(random.randint(3, 6)) # 不要爬取太快哦,小心被关进小黑屋
        html = web.page_source
        soup = bs(html, 'lxml')
        ss = soup.select('pre')[0]
        res = json.loads(ss.text)  # 转json格式
        max_id = get_info(web,res,filename,mid)  # 获取一页评论,并且返回max_id用于翻页
        page = page+1

6.3 get_info 函数
不太想解释了,下次有空再解释吧
计算年龄的函数同上文


def get_info(web,res,filename,mid):
    try :
        datalist = res['data']['data']
    except KeyError as e:
        return
    max_id = res['data']['max_id']
    for i in datalist:
        web_object = {}
        web_object['mid'] = mid

        print("\033[34m发表时间:\033[0m" + i['created_at'])
        web_object['date'] = i['created_at']

        print("\033[35m评论内容:\033[0m" + i['text'])
        web_object['text'] = i['text']

        print("\033[36m位置:\033[0m" + str(i['source'])[2:])
        web_object['ip'] = str(i['source'])[2:]

        print("\033[36m昵称:\033[0m" + i['user']['screen_name'])
        web_object['user_name'] = i['user']['screen_name']
        
        print("\033[31m个签:\033[0m" + i['user']['description'])
        web_object['status'] = i['user']['description']

        user_id = '%d' % (i['user']['id'])
        print("\033[37mid号:\033[0m" + user_id)
        web_object['user_id'] = user_id

        user_link = "https://weibo.com/"+user_id+ '?refer_flag=1001030103_'
        print("\033[36m用户主页:\033[0m" + user_link)
        web_object['user_link'] = user_link

        print("\033[32m性别:\033[0m" + i['user']['gender'])
        web_object['gender'] = i['user']['gender']

        user_follow_count = '%d' % (i['user']['follow_count'])
        print("\033[31m关注人数:\033[0m" + user_follow_count)
        web_object['follow'] = user_follow_count

        user_followers_count = (i['user']['followers_count'])
        print("\033[31m被关注人数:\033[0m" + user_followers_count)
        web_object['followers'] = user_followers_count

        # =========================================切换到用户主页的窗口
        user_url = "'" + user_link + "'"
        js = "window.open(" + user_url + ");"
        web.execute_script(js)
        time.sleep(random.randint(2, 5))
        # 切换到新窗口
        # 获得打开的第一个窗口句柄
        window_1 = web.current_window_handle
        # 获得打开的所有的窗口句柄
        windows = web.window_handles
        for current_window in windows:
            if current_window != window_1:
                web.switch_to.window(current_window)
        html = web.page_source
        soup = bs(html, 'html.parser')
        print("切换到用户主页")
        web.implicitly_wait(4)
        try:
            typehtml = soup.find("div", {'class': "woo-avatar-main woo-avatar-hover ProfileHeader_avatar2_1gEyo"})
            user_type = typehtml.find("span").get("title")
            web_object['user_type'] = user_type
            print("用户类型:", user_type)
        except AttributeError as e:
            web_object['user_type'] = '普通用户'
            print("用户类型:", '普通用户')
        # ============================点击展开============================
        button = web.find_element_by_xpath(
            '//*[@id="app"]/div[2]/div[2]/div[2]/main/div/div/div[2]/div[1]/div[1]/div[3]/div/div/div[2]')
        button.click()
        html = web.page_source
        soup = bs(html, 'html.parser')  # woo-box-item-inlineBlock ProfileHeader_item3_1bUM2,woo-box-item-flex ProfileHeader_con3_Bg19p
        infohtml = soup.findAll("div", {'class': "woo-box-item-flex ProfileHeader_con3_Bg19p"})
        # print(infohtml)
        for info in infohtml:
            str1 = str(info.get_text()).strip()
            # print(str1)
            try:
                if (keywords_check('加入微博', str1)):
                    print("加入微博时间,不是生日")
                else:
                    result = re.findall("\d{4}-\d{2}-\d{2}", str1)
                    if (len(result) != 0):
                        try :
                            print("生日:", result[0])
                            age = age_calc(result[0], '2024-01-06')
                            print(age)
                            web_object['age'] = age
                        except ValueError as e:
                            print('')
            except TypeError as e:
                print('没有年龄信息')

        # sys.exit()  # 退出当前程序,但不重启shell
        time.sleep(random.randint(2, 6))
        web.close()
        # 回到主页面
        web.switch_to.window(web.window_handles[0])
        save_data(web_object, filename)

    print(max_id)
    return max_id

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/440226.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

说说flexbox(弹性盒布局模型)及适用场景?

文章目录 一、是什么二、属性flex-directionflex-wrapflex-flowjustify-contentalign-itemsalign-contentorderflex-growflex-basisflexalign-self 三、应用场景参考文献 一、是什么 Flexible Box 简称 flex&#xff0c;意为”弹性布局”&#xff0c;可以简便、完整、响应式地…

轻松关掉电脑用户账户控制弹窗!

对于新装的或者是电脑自带的系统来说,是不是会经常遇到的一个情况是,就是在你运行某些程序或者改动一些系统设置的时候,每次都会弹出个提示框,以提示你这个操作是安全的,某一个提示还行,但是每次运行程序都有提示框弹出,就会有点烦了,那么这个提示框是什么呐,如何关闭…

如何实现企业内部ERP、OA、CRM、MES系统的快速一体化集成

在企业数字化规划中&#xff0c;企业纷纷引入ERP&#xff08;企业资源规划&#xff09;、OA&#xff08;办公自动化&#xff09;、CRM&#xff08;客户关系管理&#xff09;、MES&#xff08;制造执行系统&#xff09;、电商ERP(电商订单系统)等多种信息化管理系统&#xff0c;…

你自降门槛 我就该回头吗?

作者&#xff1a;朱溪 琥珀酒研社快评&#xff1a; 曾经的你让我高攀不起 现在的我对你爱答不理 同事的哥哥 因为拿不出30万的彩礼和女友分了 两年后他开了公司也有了钱 女友跑来求复合 同事的哥哥想都没想就拒绝了 用金钱给爱情设门槛&#xff0c;爱情黄了 一个能力…

500强企业不会告诉你的真话,计算机专业如何更好地进大厂

“世界上所有的500强企业&#xff0c;都告诉你学历不重要&#xff0c;但他们绝对不会去一般学校招聘。” 听起来很残酷&#xff0c;可这就是事实。从一所普通的学校毕业&#xff0c;“混”了一个很普通的专业&#xff0c;最后只能入职一家低薪的小公司或者无法就业&#xff0c…

Codeforces Round 931(Div.2) A~D2

A. Too Min Too Max &#xff08;数学&#xff09; 题意&#xff1a; 给定长度为 n n n的数组 a a a&#xff0c;求下列表达式的最大值&#xff0c; ( i , j , k , l ) (i,j,k,l) (i,j,k,l)为不同的索引 ∣ a i − a j ∣ ∣ a j − a k ∣ ∣ a k − a l ∣ ∣ a l − a…

C/C++的内存管理与初阶模板

引言 我们在学习C的时候&#xff0c;会经常在堆上申请空间&#xff0c;所以这个时候就体现了内存管理遍历。 图下是我们常见的计算机的内存划分&#xff1a; 我也在图下对部分变量存在的位置&#xff0c;及时标注。(如果有任何问题可以联系博主修改&#xff0c;感谢大家。) 那…

OpenAI劲敌吹新风! Claude 3正式发布,Claude3使用指南

Claude 3是什么&#xff1f; 是Anthropic 实验室近期推出的 Claude 3 大规模语言模型&#xff08;Large Language Model&#xff0c;LLM&#xff09;系列&#xff0c;代表了人工智能技术的一个显著飞跃。 该系列包括三个不同定位的子模型&#xff1a;Claude 3 Haiku、Claude 3…

Compose UI 之 MediumLarge TopAppBar

Medium&Large TopAppBar 前面文章介绍了 Small 类型的 TopAppBar&#xff1a;TopAppBar CenterAlignedTopAppBar 。下来介绍 Medium 和 Large 类型的 TopAppBar&#xff1a;MediumTopAppBar LargeTopAppBar 。 MediumTopAppBar 上面介绍了Small 类型的 TopAppBar (TopAp…

Zynq—AD9238数据采集DDR3缓存千兆以太网发送实验(二)

Zynq—AD9238数据采集DDR3缓存千兆以太网发送实验&#xff08;前导&#xff09; Zynq—AD9238数据采集DDR3缓存千兆以太网发送实验&#xff08;一&#xff09; Zynq—AD9238数据采集DDR3缓存千兆以太网发送实验&#xff08;三&#xff09; 五、实验目的 本次实验使用电脑上的…

贪吃蛇c++

#include<bits/stdc.h> #include<conio.h> // 用于获取按键输入using namespace std;const int width 20; const int height 20; int x, y, fruitX, fruitY, score; int tailX[100], tailY[100]; // 蛇的身体位置数组 int nTail; // 蛇的长度 enum eDirecton { S…

C# 用Trace.WriteLine输出调试信息无法查看

写程序就会遇见BUG&#xff0c;这时候在代码不同部位输出一些标记的信息对查找错误非常有必要&#xff0c;一般情况下我们都是使用Console.WriteLine()方法来打印信息到控制台窗口&#xff0c;但有时候使用Console.WriteLine()方法会存在不方便的情况&#xff0c;比如鄙人遇到的…

国际光伏展览会

国际光伏展览会是一个专注于太阳能光伏领域的国际性展览会。该展览会汇集了来自全球光伏行业的专业人士和企业&#xff0c;展示和交流最新的太阳能光伏技术、产品和解决方案。 国际光伏展览会通常展示各种类型的光伏产品&#xff0c;包括太阳能电池、太阳能电池板、太阳能光伏发…

C#,最小代价多边形三角剖分MCPT(Minimum Cost Polygon Triangulation)算法与源代码

1 最小代价多边形三角剖分算法 凸多边形的三角剖分是通过在非相邻顶点&#xff08;角点&#xff09;之间绘制对角线来形成的&#xff0c;这样对角线就不会相交。问题是如何以最小的代价找到三角剖分的代价。三角剖分的代价是其组成三角形的权重之和。每个三角形的重量是其周长…

2024年服装私域提升的三大妙招!

在服装行业&#xff0c;私域运营正逐渐成为主流。随着市场的演变&#xff0c;从传统的线下门店与线上电商并行模式&#xff0c;到如今的以小程序商城、企业微信、视频号、公众号等为核心的全渠道私域运营模式&#xff0c;行业的转型已显而易见。 而推动这种转型的关键因素&…

一些关于绩效提升策略的具体例子和数据

员工个人绩效提升策略&#xff1a; 持续学习与发展&#xff1a; 例子&#xff1a;某销售员工报名参加销售技巧提升课程&#xff0c;学习新的销售策略。 数据&#xff1a;经过三个月的学习与实践&#xff0c;该员工的销售额提升了20%。 目标设定与跟踪&#xff1a; 例子&#xf…

如何在Windows上使用Docker,搭建一款实用的个人IT工具箱It- Tools

文章目录 1. 使用Docker本地部署it-tools2. 本地访问it-tools3. 安装cpolar内网穿透4. 固定it-tools公网地址 本篇文章将介绍如何在Windows上使用Docker本地部署IT- Tools&#xff0c;并且同样可以结合cpolar实现公网访问。 在前一篇文章中我们讲解了如何在Linux中使用Docker搭…

OKLink2月安全月报| 2起典型漏洞攻击案例分析

在本月初我们发布的2024年2月安全月报中提到&#xff0c;2月全网累计造成损失约1.03亿美元。其中钓鱼诈骗事件损失占比11.76%。 OKLink提醒大家&#xff0c;在参与Web3项目时&#xff0c;应当仔细调研项目的真实性、可靠性&#xff0c;提升对钓鱼网站和风险项目的甄别能力&…

关于华为昇腾(Ascend)AI芯片,CANN计算架构,MindSpore深度学习框架,MindStudio开发工具

1、华为昇腾生态 深度学习之前的配置都是&#xff1a;NVIDIA GPU / CPU CUDA Tensorflow/PyTorch 后来老美禁止 NVIDIA 卖GPU芯片给我们&#xff0c;于是国内企业开始发力CPU和GPU硬件&#xff0c;成果丰硕&#xff0c;虽然与NVIDIA顶级GPU还有一些差距&#xff0c;但是也不…

基于Java的生活废品回收系统(Vue.js+SpringBoot)

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容三、界面展示3.1 登录注册3.2 资源类型&资源品类模块3.3 回收机构模块3.4 资源求购/出售/交易单模块3.5 客服咨询模块 四、免责说明 一、摘要 1.1 项目介绍 生活废品回收系统是可持续发展的解决方案&#xff0c;旨在鼓…