网络爬虫终篇:向10万级网易云用户发送定向消息

本文目标:

上篇我们获得了评论用户ID及主页地址。本篇就可以基于这些数据进行一些数据分析和市场操作。理论上学会了本文的方法,你可以在任何一个网页发送广告信息,本文具有被坏人利用的可能性,因此设置了收费,而这一套爬虫教程,如果在网易云课堂找网课教,学费要1200元左右。网课的暴利还是巨大的。

终极目标达成:

1、通过热门歌手,抓取歌曲ID。
2、通过歌曲ID,抓取评论用户ID。
3、通过评论用户ID,发送定向推送消息。
上两篇完成了步骤1、步骤2,本文完成步骤3.
总结篇:requests和selenium的区别:requests无页面的方法获取歌曲ID,速度比较快,但是只能获取一些无需登录的公开网页,如果需要用户登录和验证,requests将无法做到。
selenium的优势在于完全模仿人打开网页的操作,就好像你雇佣了一个助手帮你做事一样,非常直观,也不会被禁止访问。而且对于需要用户登录的界面(如微博等),用selenium能轻松跳过验证的麻烦环节。
上篇我们用MYSQL存储爬取用户的主页信息,本篇将支持错误重做,每处理完一条记录就打一个处理标志位Y,和我们生产系统的做法类似。


步骤1:查询用户lD和主页的表

这里需要查询userinf的表,获取存储的用户的ID和主页地址。我们需要创建一个python程序来插入这个表。
python程序命名为:getUserURLSQL.py,代码为:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
__author__ = 'luoji'

import pymysql
# from ,where, group by, select, having, order by, limit
class Mysql_pq(object):
    def __init__(self):
        self.conn = pymysql.Connect(host='127.0.0.1',
                                    port=3306,
                                    user='root',
                                    passwd='root',
                                    db='python',
                                    #创建数据库格式时用utf8mb4这个格式,因为可以存储表情等非字符
                                    charset='utf8mb4'
                                            )
        self.cursor = self.conn.cursor()

    def __del__(self):
        self.cursor.close()
        self.conn.close()

def select_userinf(id_start=141,id_end=145):
    helper = Mysql_pq()
    print('连接上了数据库python,准备插入歌曲信息')

    user_id_list ,user_name_list,user_url_list= [],[],[]
    sql = "select distinct(user_id) , user_name ,user_url from userinf  WHERE clbz = 'N' and id>= %s and id <= %s" %(id_start,id_end)
    print('sql is :',sql)
    helper.cursor.execute(sql)
    results = helper.cursor.fetchall()
    for row in results:
        user_id = row[0]
        user_name = row[1]
        user_url = row[2]

        # 打印结果
        print('user_id =', user_id)
        print('user_name =',user_name)
        user_id_list.append(user_id)
        user_name_list.append(user_name)
        user_url_list.append(user_url)
    helper.cursor.close()
    return user_id_list,user_name_list,user_url_list


if __name__ == '__main__':

    user_id_list,user_name_list,user_url_list = select_userinf(id_start=141,id_end=145)
    print('user_id_list = ',user_id_list )
    print('user_url_list = ', user_name_list)
    print('user_url_list = ', user_url_list)
    print('test over')


支持错误重做:回头更新userinf表

为了错误重做,我们处理完一条userinf就更新处理标志为Y,当出错时,程序自动跳过处理标志位Y的记录,仅仅处理处理标志位N的记录,这样就可以完成接力。
所以为了完成这个接力,我们需要在处理完一个评论用户后,回头更新userinf。我们需要创建一个python程序来插入这个表。
python程序命名为:updateUserInfSQL.py,代码为:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
__author__ = 'luoji'

import pymysql
# from ,where, group by, select, having, order by, limit
class Mysql_pq(object):
    def __init__(self):
        self.conn = pymysql.Connect(host='127.0.0.1',
                                    port=3306,
                                    user='root',
                                    passwd='root',
                                    db='python',
                                    #创建数据库格式时用utf8mb4这个格式,因为可以存储表情等非字符
                                    charset='utf8mb4'
                                            )
        self.cursor = self.conn.cursor()

    def __del__(self):
        self.cursor.close()
        self.conn.close()

def update_userinf(user_id):
    helper = Mysql_pq()
    print('连接上了数据库python,准备插入歌曲信息')

    sql = "UPDATE userinf SET clbz = 'Y' WHERE user_id= '%s'" % (user_id)
    print('sql is :', sql)
    helper.cursor.execute(sql)
    helper.conn.commit()



if __name__ == '__main__':

    user_id = '124956415'
    update_userinf(user_id)
    print('user_id = ',user_id)
    print('update  user_id  %s over' %(user_id))

定向发送消息给用户:

为了顺利跳过网页登录验证,我们本次使用selenium自动化控制模块来控制浏览器访问,这样服务器无法区分是爬虫还是用户的访问,而且用户仅需要登录一次即可。
登录这里也是有技巧的,网上很多用户想把登录也自动化,搞得程序异常复杂,因为要破解验证信息,何苦了?就像:明明到小卖部买瓶矿泉水可以喝一天,你非要证明自己聪明去找两份氢气(H2)和一份氧气(O2)来燃烧,来产生水(H2O)来喝。
具体怎么做呢?暂时保密。嘿嘿。私信、留言可得。
我们需要创建一个python程序来发送消息。

代码为:

import re
import time
import numpy as np

from flask_cors.core import LOG
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver import ChromeOptions
from getUserURLSQL import *
from updateUserInfSQL import *

def sendMessage(user_id_list,user_name_list,user_url_list):
    # 如果driver没加入环境变量中,那么就需要明确指定其路径
    # 验证于2021年2月21日
    # 直接
    # chrome_options = ChromeOptions()
    # chrome_options.add_argument('--headless')
    # chrome_options.add_argument('--no-sandbox')
    # driver = webdriver.Chrome('/root/qk_python/python/data/collect/weibo_spider/priv/chromedriver',
    #                         chrome_options=chrome_options)
    driver = webdriver.Firefox()
    #driver = webdriver.Chrome()
    driver.maximize_window()
    driver.set_page_load_timeout(30)
    driver.set_window_size(1124, 850)
    url = 'https://music.163.com/#/user/home?id=1766013257'    #初始化页面看,用于用户登录
    driver.get(url)
    print('请登录个人网易云账号。')
    time.sleep(10)     #等待登录时间

    for user_id,user_name,user_url in zip(user_id_list,user_name_list,user_url_list):
        print('now the url is :',user_url)
        driver.get(user_url)
        time.sleep(3)
        print('开始准备发消息')
        driver.switch_to.frame('g_iframe')  # 网易云的音乐元素都放在框架内!!!!先切换框架

        print('准备点击私信')

        href_xpath = "//div[contains(@class,'g-wrap p-prf')]//div[contains(@class,'name f-cb')]//a[contains(@class,'btn u-btn u-btn-7 f-tdn')]"
        submit = driver.find_element_by_xpath(href_xpath)
        print('定位私信成功')
        ActionChains(driver).double_click(submit).perform()
        ActionChains(driver).click(submit).perform()

        time.sleep(2)

        text_xpath = "//div[contains(@class,'item f-cb')]//div[contains(@class,'ct j-flag')]//div[contains(@class,'u-txtwrap f-pr')]//textarea[contains(@class,'u-txt area j-flag')]"
        text_field = driver.find_element_by_xpath(text_xpath)
        print('清空输入框')
        text_field.clear()
        message = user_name +',祝你新年快乐。2021天天开心。'    #私信内容
        text_field.send_keys(message)

        #点击发送信息
        send_xpath = "//div[contains(@class,'item f-cb')]//div[contains(@class,'ct j-flag')]//div[contains(@class,'btns f-cb f-pr')]//a[contains(@class,'f-fr u-btn u-btn-1 j-flag')]"
        send_buttom = driver.find_element_by_xpath(send_xpath)
        print('定位到了发送按钮')
        ActionChains(driver).click(send_buttom).perform()
        print('发送完毕')
        time.sleep(1)       #等待一个发送延迟时间
        update_userinf(user_id)     #标记用户状态为已发送,支持错误重做。
        print('user_id = %s is updated ,准备下一个用户.' %(user_id))


if __name__ == '__main__':

    id_start, id_end = 145, 148   #定义查询用户的范围,以便于做到多进程并行发送。每个程序查询一部分ID范围的用户
    user_id_list,user_name_list,user_url_list = select_userinf(id_start, id_end)     #获取用户信息

    sendMessage(user_id_list,user_name_list,user_url_list)    #发送消息

发送时的结果如下:
在这里插入图片描述
在这里插入图片描述

这里有几点说明:
1、 userinf中用户的id是个自增的数,可以用来做多进程并发控制,每个进程读取一段id段。加快发送速度。
2、每个进程的浏览器相互不会干扰,不会串。

至此,学完这3个步骤,你就具备向10w级别的用户发消息了。省了1200元的学费,岂不痛快哉!!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值