この記事の目的:
前回の記事では、人気歌手の曲のIDとURLアドレスを取得しました。この記事では、コメントのユーザーIDとホームページアドレスをさらに取得します。最終目標:
1.人気の歌手から曲IDを取得します。
2.ソングIDを使用して、コメントユーザーIDをキャプチャします。
3.ユーザーIDにコメントして、ターゲットを絞ったプッシュメッセージを送信します。
前の記事はステップ1を完了し、この記事はステップ2を完了しました。
余談:前の記事でページなしで曲IDを取得するために使用したリクエスト方法は高速ですが、約2000を取得すると、クローラーとして認識され、サーバーによって禁止されます。携帯電話のホットスポットに接続して、接続する前にフライトモードを再開してください。さらに2,000を取得できます。
前回の記事では、MYSQLを使用してクロール結果を保存しました。今回は同じ方法を使用します。同時に、この記事ではエラーのやり直しをサポートします。レコードが処理されるたびに、処理フラグYがマークされます。これは私たちの生産システムに似ています。
ステップ1:mysqlテーブルを作成する
ここでは、userinfというテーブルを作成して、ユーザーのID、コメント時間、およびホームページアドレスを格納する必要があります。
テーブル作成ステートメントは次のとおりです。
DROP TABLE IF EXISTS `userinf`;
CREATE TABLE `userinf` (
`id` int(12) NOT NULL AUTO_INCREMENT,
`user_id` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`user_name` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci ,
`user_time` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci ,
`user_url` varchar(400) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`clbz` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci ,
`bysz` float(3, 0) NULL DEFAULT 0.00,
PRIMARY KEY (`id`) USING BTREE,
INDEX `user_id`(`user_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
作成後、このテーブルを挿入するPythonプログラムを作成する必要があります。
Pythonプログラムの名前はuseridSpiderSQL.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 modify_sql(self,sql,data):
self.cursor.execute(sql,data)
self.conn.commit()
def __del__(self):
self.cursor.close()
self.conn.close()
def insert_userinf(user_id,user_name,user_time,user_url,clbz):
helper = Mysql_pq()
print('连接上了数据库python,准备插入歌曲信息')
# 插入数据
insert_sql = 'insert into userinf(user_id,user_name,user_time,user_url,clbz) value (%s,%s,%s,%s,%s)'
data = (user_id,user_name,user_time,user_url,clbz)
helper.modify_sql(insert_sql, data)
if __name__ == '__main__':
# helper = Mysql_pq()
# print('test db')
# #测试
# insert_sql = 'insert into weibo_paqu(werbo) value (%s)'
# data = ('222222xxxxxx2222 ',)
# helper.modify_sql(insert_sql,data)
user_id='519250015'
user_name= '请记住我'
user_url = 'https://music.163.com/#/song?id=1313052960&lv=-1&kv=-1&tv=-1'
user_time = '2021年2月18日'
clbz = 'N'
insert_userinf(user_id,user_name,user_time,user_url,clbz)
print('test over')
エラーやり直しのサポート:戻ってsonginfテーブルを更新します
エラーをやり直すために、songinfの処理後に処理フラグをYに更新します。エラーが発生すると、プログラムは処理フラグビットYのレコードを自動的にスキップし、処理フラグビットNのレコードのみを処理します。リレーが完了できます。
したがって、このリレーを完了するには、曲のコメントユーザーをクロールした後、戻ってsonginfを更新する必要があります。このテーブルに挿入するPythonプログラムを作成する必要があります。
Pythonプログラムの名前はupdateSongURLSQL.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 updater_songurl(url):
helper = Mysql_pq()
print('连接上了数据库python,准备插入歌曲信息')
sql = "UPDATE songinf SET clbz = 'Y' WHERE song_url= '%s'" % (url)
print('sql is :', sql)
helper.cursor.execute(sql)
helper.conn.commit()
if __name__ == '__main__':
url = 'https://music.163.com/#/song?id=569213220&lv=-1&kv=-1&tv=-1'
updater_songurl(url)
print('urllist = ',url )
print('update over')
コメントユーザーのクロール:
サーバーによる禁止を防ぐために、今回はセレン自動化制御モジュールを使用してブラウザーアクセスを制御し、サーバーがクローラーとユーザーアクセスを区別できないようにします。欠点は、速度が比較的遅いことです。現在のクロール速度1時間あたり約1000のユーザーデータです。
一晩走った後、100,000以上のユーザーIDを取得しました。ここでは、前の記事で取得した曲のURL情報を使用する必要があり、このテーブルを挿入するPythonプログラムを作成する必要があります。
Pythonプログラムの名前はgetSongURLSQL.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 modify_sql(self,sql,data):
# self.cursor.execute(sql,data)
# self.conn.commit()
def __del__(self):
self.cursor.close()
self.conn.close()
def select_songurl():
helper = Mysql_pq()
print('连接上了数据库python,准备插入歌曲信息')
urllist = []
sql = "SELECT * FROM songinf WHERE clbz = 'N'"
helper.cursor.execute(sql)
results = helper.cursor.fetchall()
for row in results:
id = row[0]
song_id = row[1]
song_name = row[2]
song_url = row[3]
clbz = row[4]
# 打印结果
print('id =', id)
print('song_url =',song_url)
urllist.append(song_url)
return urllist
if __name__ == '__main__':
# helper = Mysql_pq()
# print('test db')
# #测试
# insert_sql = 'insert into weibo_paqu(werbo) value (%s)'
# data = ('222222xxxxxx2222 ',)
# helper.modify_sql(insert_sql,data)
# song_id='519250015'
# song_name= '请记住我'
# song_url = 'https://music.163.com/#/song?id=1313052960&lv=-1&kv=-1&tv=-1'
# clbz = 'N'
urllist = select_songurl()
print('urllist = ',urllist )
print('test over')
したがって、データベースmysqlは非常に重要です。
コードは次のとおりです。
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 getSongURLSQL import *
from useridSpiderSQL import *
from updateSongURLSQL import *
def is_number(s):
try:
float(s)
return True
except ValueError:
pass
try:
import unicodedata
unicodedata.numeric(s)
return True
except (TypeError, ValueError):
pass
return False
def geturl(urllist):
# 如果driver没加入环境变量中,那么就需要明确指定其路径
# 验证于2021年2月19日
driver = webdriver.Firefox()
#driver = webdriver.Chrome()
driver.maximize_window()
driver.set_page_load_timeout(30)
driver.set_window_size(1124, 850)
# locator = (By.)
for url in urllist:
print('now the url is :',url)
driver.get(url)
time.sleep(3)
print('开始登陆')
driver.switch_to.frame('g_iframe') # 网易云的音乐元素都放在框架内!!!!先切换框架
href_xpath = "//div[contains(@class,'cntwrap')]//div[contains(@class,'cnt f-brk')]//a[contains(@class,'s-fc7')]"
songid = driver.find_elements_by_xpath(href_xpath)
useridlist = []
usernamelist = []
for i in songid:
userurl = i.get_attribute('href')
userid = userurl[35:] #用户的id数字
print('userid = ',userid)
username = i.text
print('username = ',username)
try:
print('userid is ',userid)
if is_number(userid) : #说明是纯数字
print('用户id是数字,保留')
useridlist.append(userid)
usernamelist.append(username)
else:
iter
except (TypeError, ValueError):
print('用户id非数字,丢弃')
iter
#获取用户评论时间
commenttimelist=[]
time_xpath = "//div[contains(@class,'cntwrap')]//div[contains(@class,'rp')]//div[contains(@class,'time s-fc4')]"
songtime = driver.find_elements_by_xpath(time_xpath)
for itime in songtime:
#print(i.get_attribute('href'))
commenttime = itime.text
print('commenttime = ',commenttime)
commenttimelist.append(commenttime)
if len(commenttimelist)< len(useridlist):
for i in np.arange(0,len(useridlist)-len(commenttimelist),1):
commenttimelist.append('2021年2月18日')
print('len(useridlist) is = ',len(useridlist))
for i in np.arange(0,len(useridlist),1):
userid_i = useridlist[i]
username_i = usernamelist[i]
commenttime_i = commenttimelist[i]
#插入到数据库中
print('userid_i=',userid_i)
print('username_i=', username_i)
print('commenttime_i=', commenttime_i)
userurl_i ='https://music.163.com/#/user/home?id=' + str.strip(userid_i)
print('userurl_i=', userurl_i)
clbz = 'N'
try:
insert_userinf(userid_i, username_i, commenttime_i, userurl_i, clbz)
except :
print('插入数据库有错')
pass
time.sleep(5)
updater_songurl(url)
def is_login(source):
rs = re.search("CONFIG\['islogin'\]='(\d)'", source)
if rs:
return int(rs.group(1)) == 1
else:
return False
if __name__ == '__main__':
#url = 'https://music.163.com/#/discover/toplist?id=2884035'
urllist = select_songurl()
# urllist =['https://music.163.com/#/song?id=569200214&lv=-1&kv=-1&tv=-1','https://music.163.com/#/song?id=569200213&lv=-1&kv=-1&tv=-1']
geturl(urllist)
キャプチャの結果は次のとおりです。
いくつかの説明があります:
1。最新のコメントのページめくりをしませんでした。やりたい場合は、ページめくりボタンをクロールしてクリックし、もう一度やり直す必要があります。 -ユーザーIDを取得します。
2.特定のコメントの内容は一時的に保存されません。
3.削り取られたコメントの日付情報の形式は非常に不規則であり、フォローアップ処理が必要です。
次のパートでは、ステップ3を完了し、10wレベルのユーザーに曲をプッシュすることができます。