由于平时喜欢刷微博,追星,所以写了想要写一个爬取微博的爬虫,在老师的建议下选择从移动端爬取,因为移动端页面元素简洁,易于爬取。在看微博时发现有比移动端更加简单的一个版本。。。。老年机版?就是分页式的。
在网上看了一些爬取微博的爬虫,采取cookie模拟登陆,cookie直接在chrome按f12选择Network点击第一个网页,再点右边的Headers–>Request Headers,赋值下面的cookie即可。百度可以很轻松的找到方法。
想清楚上面的问题后就开始分析移动端的网页构造了,经过分析源代码,发现微博总页数是一个input标签的value属性,而input标签的name属性为’mp’,这是唯一的。然后每条微博的代码块由div标签闭合,含有id属性并且class属性的值均为’c’。微博内容的标签为span,span标签的class属性的值为‘ctt’然后微博发送时间和客户端的标签为span标签,span标签的class属性的值为’ct’,这也是发送时间的代码块特有的属性值。
下面是详细代码:
import requests
from bs4 import BeautifulSoup as bs
import pymysql
# uid即进入对方微博主页后网址部分/u/后的那一串数字
uid = input('请输入所要爬取的用户id:')
url= 'https://weibo.cn/u/'+uid
cookie = '你的cookie'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36',
'Cookie': cookie}
res = requests.get(url, headers=headers)
soup = bs(res.text, 'html.parser')
#获得微博总页数
totalPage = int(soup.find('input', attrs={'name': 'mp'}).attrs['value'])
print('总共检测到%d页微博页面' % totalPage)
#定义各列表
weibo_text=[]
weibo_images=[]
weibo_time=[]
weibo_client=[]
weibo_urlList=[]
# 每页微博的URL的列表
for i in range(totalPage):
weibo_urlList.append(url+'page='+str(i + 1)')
#遍历每页微博
for each in weibo_urlList:
r= requests.get(each , headers=headers)
soup = bs(r.text, 'html.parser')
# 每条微博所对应的标签代码块列表
weibo_tags_list = soup.find_all('div', attrs={'class': 'c'}, id=True)
for weibo_tag in weibo_tags_list:
# 获取微博发送时间
hms = weibo_tag.find_all('span', attrs={'class': 'ct'})
for each_time in hms :
weibo_time .append(each_time.text.replace('\xa0', ' ').split(' ')[0]+each_time.text.replace('\xa0', ' ').split(' ')[1])
#获取客户端
for each_client in hms :
weibo_client .append(each_time.text.replace('\xa0', ' ').split(' ')[2])
#获取微博文本内容
texts=weibo_tag.find_all('span',attrs={'class':'ctt'})
for each_text in texts :
weibo_text .append(each_text.text)
try:
#连接数据库
# conn = pymysql.connect(host='localhost', port=3306, user='root', password='root', database='weibo', charset='utf8mb4')
conn = pymysql.connect(host=' ', port=3306, user='', password='', database='weibo', charset='utf8mb4')
cursor = conn.cursor()
#创建表
cursor.execute('create table weibo_info (id INT AUTO_INCREMENT PRIMARY KEY,weibo_time VARCHAR(45),weibo_client VARCHAR (45) ,weibo_text VARCHAR(500))')
for i in range(len(weibo_time)):
cursor.execute('insert into weibo_info(weibo_time,weibo_client,weibo_text)VALUES(%s,%s,%s)',(weibo_time[i],weibo_client[i],weibo_text[i]))
cursor.fetchall()
# 提交结果
conn.commit()
print("结果已提交")
except Exception as e:
# 数据回滚
conn.rollback()
print("数据已回滚")
# 关闭数据库
conn.close()
需要注意的是数据库utf8下文字是三字节,但是emoji是四字节,微博内容有许多emoji表情,需要将编码改成utf8mb4。
在此次练习中出现了许多的问题,并且最终结果也与我初次设计的结果有一些出入,还需要改进很多,在调试过程中更是非常耗费耐心排除问题,希望以后能够再接再厉。