对于上一篇的微博OCR提取热搜的方法显得十分笨拙,本篇用scrapy干净利落地解决了问题。
1. 写爬虫爬取热搜网页内容
微博热搜页http://s.weibo.com/top/summary是不需要登陆就可以获得的,但是文本不在html网页框架中,而是利用一个连接新的get得到的html,里面包含了内容的编码。scrapy新建三连省略了,列出爬虫主体:
# -*- coding: utf-8 -*-
import scrapy
class WeiboSpiderSpider(scrapy.Spider):
name = 'weibo_spider'
allowed_domains = ['weibo.com']
start_urls = ['http://s.weibo.com/ajax/jsonp/gettopsug?uid=&ref=PC_topsug&url=http://s.weibo.com/top/summary&Mozilla=Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0&_cb=STK_15287494731273']
def parse(self, response):
f=open("weibo.txt","w")
f.write(response.body)
十分简洁,下载好的网页内容包含在weibo.txt中。
2. 写主函数获得数据内容并写入数据库
思路也一目了然,用正则提取出note\num的内容,然后将内容一并写入数据库中:
# -*- coding=utf-8-*-
import re
import sqlite3
import time
import scrapy
import os
# 执行爬虫
os.system('scrapy crawl weibo_spider')
# 解析文本并保存文本
f=open("weibo.txt",'r')
contents=f.read()
f.close()
item_contents=re.findall('[\d\w\\\\]+(?=","word")',contents)
nums=re.findall('"num":"\d+"',contents)
mycontent=[]
for item in (item_contents):
content=item.decode('unicode_escape')
mycontent.append(content)
print(content)
mynum=[]
for num in nums:
newnum=re.search('\d+',num).group()
newnum=int(newnum)
mynum.append(newnum)
print(newnum)
# 写入数据库
cx = sqlite3.connect("E:\ATang\MyDatabase\Weibo.db")
print 'Opened database successfully'
mytime = time.strftime('%Y%m%d',time.localtime(time.time()))
shumu=len(mycontent)
for i in range(0,shumu):
sql = "insert into WeiboRedian(date,note,num)values('%s','%s',%d)" % (mytime,mycontent[i],mynum[i])
cx.execute(sql)
cx.commit()
cx.close()
这个脚本也十分简洁,可以看出scrapy在读取规则的网络数据比之前用到的OCR方法好太多了。关于脚本内容的细节,可以参考scrapy学习笔记中的内容。但是前述方法也并非一无是处,在正则表达式失效的场合,文本识别技术或者机器分类就变得极为重要了。
如果在主函数加入时间循环,或者改造成exe运行程序用windows系统每天调用的话,可以做到让他每天都能爬取到微博热点信息并汇成数据表,以供语义分析和词云的制作。