爬虫实战(一):爬取微博用户信息

爬虫实战(一):爬取微博用户信息

2023年6月29日发(作者:)

爬⾍实战(⼀):爬取微博⽤户信息前⾔最近做课设,是⼀个有关个⼈隐私安全的课题,在⽹上找了很多论⽂,最后上海交通⼤学的⼀篇硕⼠论⽂《⾯向社会⼯程学的SNS分析和挖掘》[1] 给了我很多灵感,因为是对个⼈隐私安全进⾏评估,所以我们基于微博社交⽹络获取的数据进⾏分析。以下是该系列第⼀篇⽂章,记录爬取微博⽤户信息的过程。先决条件我们这次的⽬标是爬取微博个⼈⽤户的资料信息和动态信息并保存在 mysql 数据库中。⾸先要对⽹页进⾏⼤致分析,获取爬⾍的先决条件。cookies因为微博对访客进⾏了限制,所以请求⾥⾯没有 cookies 的话动态⽆法抓取完全。故我们也需要获取 cookie:⽤Chrome打开/signin/login;按F12键打开Chrome开发者⼯具;点开“Network”,将“Preserve log”选中,输⼊微博的⽤户名、密码,登录点击Chrome开发者⼯具“Name"列表中的"",点击"Headers",其中"Request Headers"下,"Cookie"后的值即为我们要找的cookie值,复制即可UID⽤户资料页⽹页分析获取了 uid 和 cookie ,我们来对⽹页进⾏详细分析。⽤户资料页源码分析因为资料页数据量很少,分析和处理都⽐较容易,所以⾸先从这⾥下⼿。由上⼀张图⽚可以看出,资料页分成 **基本信息 ,学习经历,⼯作经历,其他信息 ** 四个模块,我们只需要前三个模块就可以了。分析源码的html ,我们发现

class="tip"> 刚好可以标识四个信息模块,⽽对于每个模块内部的资料条⽬,class="c" 可以进⾏⼀⼀标识,如图所⽰:资料页源码使⽤正则表达式进⾏匹配,关于正则表达式的使⽤⽅法,请看我的另⼀篇⽂章。代码如下:tip = e(r'class="tip">(.*?)>

', re.S) #匹配四个模块所有内容title = e(r'(.*?)
(.*?)

,并且⼀⼀对应。⽽动态发布时间⼀⼀对应

,如图所⽰:动态页源码正则表达式代码如下:dynamic = e(r'.*?>(.*?)(.*?) ', re.S) # 匹配动态发布时间可以从第⼀页中获取页数:page_number = e(r'.*/(d*?)页

', re.S) # 匹配动态页数爬取信息有了前⾯的铺垫,爬取⽤户资料便⽐较容易实现了。对于⽤户资料,使⽤前⾯的正则表达式对爬去的页⾯进⾏处理,有以下代码:tip = e(r'class="tip">(.*?)>
', re.S) #匹配四个模块所有内容title = e(r'(.*?)(.*?)
(.*?)
(.*?) ', re.S) # 匹配动态发布时间page_number = e(r'.*/(d*?)页', re.S) # 匹配动态页数dys = l(dynamic, )ts = l(times, )pages = l(page_number, )pagenums = pages[0]mainurl = urllabel = 0 # 标签⽤于计数,每5~20次延时10Stag = t(5, 20)for pagenum in range(int(pagenums))[1:]: if (label == tag): (10) label = 0 tag = t(5, 20) # 随机选择,防⽌被ban cookie = (cookies) cookie = getcookies(cookie) headers = { 'User_Agent': (user_agents) } pagenum += 1 label += 1 url = mainurl + '?page=' + str(pagenum)#更改页数 page = gethtml(url, headers, cookie, conf, use_proxies) dys += l(dynamic, ) ts += l(times, )dys = dys[1:]⾄此爬⾍这部分代码基本上完成。保存数据到数据库如果没有保存在数据库的需要,可以不⽤阅读该部分。本来之前是使⽤ pymysql + SQL语句实现数据库操作,但是这样太繁琐了,并且这些访问数据库的代码如果分散到各个函数中,势必⽆法维护,也不利于代码复⽤。所以在这⾥我使⽤ORM框架(SQLAlchemy)来操作数据库,该框架实现了对数据库的映射操作,即封装了数据库操作,简化代码逻辑。⾸先创建三个表:# 微博⽤户信息表 wb_user = Table('wb_user', metadata, Column('user_ID', Integer, primary_key=True, autoincrement=True), # 主键,⾃动添加 Column("uid", String(20), unique=True, nullable=False), # 微博⽤户的uid Column("Uname", String(50), nullable=False), # 昵称 Column("Certified", String(50), default='', server_default=''), # 认证信息 Column("Sex", String(200), default='', server_default=''), # 性别nullable=False Column("Relationship", String(20), default='', server_default=''), # 感情状况 Column("Area", String(500), default='', server_default=''), # 地区 Column("Birthday", String(50), default='', server_default=''), # ⽣⽇ Column("Education_info", String(300), default='', server_default=''), # 学习经历 Column("Work_info", String(300), default='', server_default=''), # ⼯作经历 Column("Description", String(2500), default='', server_default=''), # 简介 mysql_charset='utf8mb4' ) # 微博⽤户动态表 wb_data = Table('wb_data', metadata, Column('data_ID', Integer, primary_key=True, autoincrement=True), # 主键,⾃动添加 Column('uid', String(20), ForeignKey(wb_), nullable=False), # 外键 Column('weibo_cont', TEXT, default=''), # 微博内容 Column('create_time', String(200), unique=True), # 创建时间,unique⽤来执⾏upsert操作,判断冲突 mysql_charset='utf8mb4' ) # 动态主题表 wb_topic = Table('wb_topic', metadata, Column('topic_ID', Integer, primary_key=True, autoincrement=True), # 主键,⾃动添加 Column('uid', String(20), ForeignKey(wb_), nullable=False), # 外键 Column('topic', Integer, nullable=False), # 主题-----默认5类 Column('topic_cont', String(20), nullable=False, unique=True), # 主题内容 mysql_charset='utf8mb4' )这⾥有⼀个细节需要注意,那就是 mysql 的编码使⽤了utf8m64的编码⽅式,为什么要使⽤这种⽅式呢?因为微博⾥⾯的emoji 表情占4个字节,超过了utf-8 编码范围:UTF-8 是 3 个字节,其中已经包括我们⽇常能见过的绝⼤多数字体,但 3 个字节远远不够容纳所有的⽂字, 所以便有了utf8mb4 , utf8mb4 是 utf8 的超集,占4个字节, 向下兼容utf8。使⽤ utf8mb4 要求:MySQL数据库版本>=5.5.3MySQL-python 版本 >= 1.2.5然后我们将爬⾍获取的信息存到数据库中,⾸先是资料页数据:from sqlalchemy import MetaData, Tablefrom import insertins = _duplicate_key_update(# 如果不存在则插⼊,存在则更新(upsert操作#/en/latest/dialects/#mysql-insert-on-duplicate-key-#update) Uname=Uname, Certified=Certified, Sex=Sex, Relationship=Relationship, Area=Area, Birthday=Birthday, Education_info=Education_info, Work_info=Work_info, Description=Description)e(ins)ins = insert(table).values(uid=uid, Uname=Uname, Certified=Certified, Sex=Sex, Relationship=Relationship,Area=Area,Birthday=Birthday,Education_info=Education_info,W接着是动态数据保存在数据库中:re_nbsp = e(r' ', re.S) # 去除$nbspre_html = e(r']*>', re.S) # 去除html标签re_200b = e(r'u200b', re.S) # 去除分隔符re_quot = e(r'"', re.S)for i in range(len(ts)):#len(ts)为动态数 #去除噪声 dys[i] = re_('', dys[i]) dys[i] = re_('', dys[i]) dys[i] = re_('', dys[i]) dys[i] = re_('', dys[i]) ins = insert(table).values(uid=uid, weibo_cont=_string(dys[i]), create_time=ts[i]) ins = _duplicate_key_update(weibo_cont=_string(dys[i])) e(ins)尾声下⼀篇介绍⼀下对获取的数据进⾏处理的过程。参考:[1]陆飞.⾯向社会⼯程学的SNS分析和挖掘[D].上海:上海交通⼤学,2013.

发布者:admin,转转请注明出处:http://www.yc00.com/web/1687982744a63549.html

相关推荐

发表回复

评论列表(0条)

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信