-
2022-06-19 02:02:00更多相关内容
-
微博关键词爬虫_微博关键词爬虫_
2021-09-29 11:21:47收集的开源者的微博爬虫代码,主要根据不同关键词搜索来对结果进行翻页的爬取,收集结果的【"rid" -
超级详细scrapy爬虫教程;微博关键词爬虫;整个爬虫的编写与思路;最终爬取“EDG”有关微博生产词云。
2021-11-09 07:54:52微博关键词爬虫;超详细爬虫教程;整个爬虫编写流程和思路;Xpath表达式编写;数据存储和处理微博关键词爬虫;超详细爬虫教程;整个爬虫编写流程和思路;Xpath表达式编写;数据存储和处理
我们大家都知道一般来说,要爬取微博的相关信息,还是weibo.cn这个站点要好爬取一些。但是这个站点却没有关键词检索,所以我们不能根据自己想搜索的关键词去爬取自己想要的内容。不过博主发现,微博有一个站点:“s.weibo.com”。这是一个专门根据关键词来检索相关微博的站点,下面我就该站点,利用scrapy爬取相关微博内容来为大家详细讲解其中的过程。
可以爬取的字段
首先展示可以爬取那些字段:
有了数据要怎么分析就是大家自己的事情了。下面我们详细介绍怎么去爬取这些数据。一,网页分析
首先我们进入s.weibo.com,输入自己想要搜索的内容,如何按F12,观察网页格式。
要提取网页中自己想要的内容,我们选择用xpath去获取,scrapy中也有.xpath()的方法,方便我们爬虫的编写。这里教大家一个小技巧,我们选中自己想要标签后可以右键,如何选择copy xpath,就可以复制该标签的xpath表达式,如何我们按住Ctrl+F,将复制的表达式放入搜索框,然后我们就可以直接在后面修改表达式,就可以提取该标签或者和该标签同级的标签下相应的内容了。这一步非常重要,可以提高我们后面编写代码的编写效率。
比如我们在这里复制了该页面第一条内容的xpath表达式,然后我修改表达式提取到同类标签。
可以看见,该类标签有22个,我数了一下,该页面下刚好有22条微博,那么接下来,我们只需要在这个xpath表达式后面增加内容就可以进一步提取自己想要的字段了。下面我们以微博的文本内容为例。
首先我们先选择中微博的文本内容:
然后查看标签
此时我们只需要把p标签的文本提取出来就行,首先我们要定位p标签,在刚才的xpath表达式后面加上:“//p[@node-type=“feed_list_content””,这样我们就选中了了该页面下所有微博的文本内容了。其他的字段也是同样的道理,我们把所有字段的xpath表达式弄出来,在后面爬虫的时候再来具体处理。
二,爬虫部分
爬虫部分我们,采取scrapy框架编写,对于这个框架的安装和怎么创建一个项目我就不详细介绍了,大家可以自行查找资料。
在创建好项目,生产spider后,我们首先编写item.py,把我们要爬取的字段,先在item中定义好。from scrapy import Item, Field class KeywordItem(Item): """ 关键词微博 """ keyword = Field() weibo_url = Field() content = Field() weibo_id = Field() crawl_time = Field() created_at = Field() tool = Field() repost_num = Field() comment_num = Field() like_num = Field() user_url = Field() user_id = Field()
然后编写pipeline.py,对爬虫进行本地数据库存储。
import pymongo from pymongo.errors import DuplicateKeyError from settings import MONGO_HOST, MONGO_PORT class MongoDBPipeline(object): def __init__(self): client = pymongo.MongoClient(MONGO_HOST, MONGO_PORT) db = client['edg'] self.Keyword = db["Keyword"] def process_item(self, item, spider): self.insert_item(self.Keyword, item) @staticmethod def insert_item(collection, item): try: collection.insert(dict(item)) except DuplicateKeyError: pass
首先是初始化函数,定义好数据库的端口、名称和表的名称;然后process_item函数把item字段都插入到表Keyword中去,item是scrapy的一大特点,它类似于字典这一数据结构,爬虫部分将爬取到的数据存在item中然后提交给管道,进行存储。
然后我们开始写爬虫部分,在spider文件夹下面创建keyword.py,在start_requests中先定义好要爬取的网页和headers等。
def start_requests(self): headers = { 'Host': 's.weibo.com', 'Cookie': '' } keywords = ['edg'] url = 'https://s.weibo.com/weibo?q={}&Refer=index&page=1'
那么我们要爬取数据肯定就不能只是爬取一页的数据,根据观察网站的URL我们可以发现有一个page参数,我们只需要构造该参数的值就可以实现生成不同页面的URL,我把他放在一个URL列表中,循环访问就可以了。
urls = [] for keyword in keywords: urls.append(url.format(keyword)) for url in urls: yield Request(url, callback=self.parse,headers=headers)
然后我们来写爬虫处理函数parse。
def parse(self, response): if response.url.endswith('page=1'): page = 50 for page_num in range(2, page+1): page_url = response.url.replace('page=1', 'page={}'.format(page_num)) yield Request(page_url, self.parse, dont_filter=True, meta=response.meta) if response.status == 200: html_result = response.text data = etree.HTML(html_result) nodes = data.xpath('//div[@class="card"]')
首先是要判断URL最后的page参数是不是为1,如果是,那么我们将page复制为50(因为该网站最多显示50页的微博内容),然后用format方法构造50个URL,每个都递交给parse方法去处理。
如果访问成功,就提取去所有的“//div[@class=“card”]”赋值给nodes,这是我们上面网页分析是提取的所有的包含微博内容的xpath表达式。然后就在nodes循环提取所有的文本内容。for node in nodes: try: content = node.xpath('.//p[@node-type="feed_list_content"]') keyword_item['content']=extract_weibo_content(content[0].xpath('string(.)').strip()) yield keyword_item except Exception as e: self.logger.error(e)
这里我们只以提取微博文本内容为例
只需要将刚才在“//div[@class=“card”]”后面增加的提取的微博文本内容的xpath表达式,提取到content中,处理后在放入keyword_item(刚才说了它是类似于字典结构,用法跟字典都是一样的)中。怎么处理才能将所有的文本都提取出来呢,这个就需要大家不断的尝试,像我也是尝试很多次才知道是使用.xpath(‘string(.)’)。最后不要忘记提交给item哦。
extract_weibo_content()是一个处理提取文本中多余的表情,符号和网址的函数。代码如下:
def extract_weibo_content(weibo_html): s = weibo_html if 'class="ctt">' in s: s = s.split('class="ctt">', maxsplit=1)[1] s = emoji_re.sub('', s) s = url_re.sub('', s) s = div_re.sub('', s) s = image_re.sub('', s) if '<span class="ct">' in s: s = s.split('<span class="ct">')[0] splits = s.split('赞[') if len(splits) == 2: s = splits[0] if len(splits) == 3: origin_text = splits[0] retweet_text = splits[1].split('转发理由:')[1] s = origin_text + '转发理由:' + retweet_text s = white_space_re.sub(' ', s) s = keyword_re.sub('', s) s = s.replace('\xa0', '') s = s.strip(':') s = s.strip() return s
三,数据爬取与处理
然后我们就可以开始运行爬虫了。
可以看见爬虫运行是没有问题的,我是使用一个ip和单个账号进行爬取的,经过测试,速度大概是一个小时能爬一万条。最后在monogodb中查看我们爬取的数据,同时我还爬取了微博的评论
这里数据量有点少,主要是因为我爬了一会就停了,大家想要多爬些的,可以自己试试。
有了数据,想要怎么分析,就是后面的事情了,起码做饭我们是有米了。这里生产了微博和评论的词云
本人也是爬虫爱好者,希望写这篇文章能帮助到一些刚入门的人,欢迎大家一起交流和各位大佬批评指正。 -
微博关键词爬虫——基于requests和aiohttp
2020-12-08 14:00:28requests库是python爬虫中最常见的库,与内置的urllib库相比,它更加简洁高效,是每一个接触爬虫者都务必要掌握的基础;但它也是有缺点的,就是不支持异步操作,虽然可以通过多线程来解决,但当需要发送大量请求时,...requests库是python爬虫中最常见的库,与内置的urllib库相比,它更加简洁高效,是每一个接触爬虫者都务必要掌握的基础;但它也是有缺点的,就是不支持异步操作,虽然可以通过多线程来解决,但当需要发送大量请求时,创建大量的线程会浪费过多的资源;此时出现了一个新的库aiohttp,它是支持异步操作的,可以在一个线程中,通过异步多任务来实现快速发送请求,提高效率。这次,我基于这两个库,做一个高效的微博关键词爬虫,源码在文章的末尾。
首先,我是从微博的移动端地址入手,发现它是ajsx请求,请求参数中,除页码外,其他都是常量,所以要实现多页请求,直接将页码当作参数发送即可。但是页面返回的json数据并没有直接标明总页数,所以需要自己计算。进一步分析,发现数据中包含了微博的总条数和每一页的条数,这就是突破口,对它进行简单的运算就可以拿到总页码。此处只需要发送一次请求,就可以获取到信息,所以这里采用的是requests。
defget_page():"""先用requests构造请求,解析出关键词搜索出来的微博总页数
:return: 返回每次请求需要的data参数"""data_list=[]
data={'containerid': '100103type=1&q={}'.format(kw),'page_type': 'searchall'}
resp= requests.get(url=url, headers=headers, params=data)
total_page= resp.json()['data']['cardlistInfo']['total'] #微博总数
#一页有10条微博,用总数对10整除,余数为0则页码为总数/10,余数不为0则页码为(总数/10)+1
if total_page % 10 ==0:
page_num= int(total_page / 10)else:
page_num= int(total_page / 10) + 1
#页码为1,data为当前data,页码不为1,通过for循环构建每一页的data参数
if page_num == 1:
data_list.append(data)returndata_listelse:for i in range(1, page_num + 1):
data['page'] =i
data_list.append(copy.deepcopy(data))return data_list
页码解析
获取完页码之后,就可以进行数据解析。每一页都需要单独发送请求,为了提高效率,此处采用的是aiohttp。通过async关键词来定义特殊函数,返回一个协程对象,注意函数内部所有代码必须是支持异步操作的。在构建请求的时候需要注意特定的格式。
#async定义函数,返回一个协程对象
async defcrawl(data):"""多任务异步解析页面,存储数据
:param data: 请求所需的data参数
:return: None"""async with aiohttp.ClientSession() as f:#实例化一个ClientSession
async with await f.get(url=url, headers=headers, params=data) as resp: #携带参数发送请求
text = await resp.text() #await 等待知道获取完整数据
text_dict = json.loads(text)['data']['cards']
parse_dict={}for card intext_dict:if card['card_type'] == 9:
scheme= card['scheme']if card['mblog']['isLongText'] isFalse:
text= card['mblog']['text']
text= re.sub(r'<.>|\n+', '', text)else:
text= card['mblog']['longText']['longTextContent']
user= card['mblog']['user']['profile_url']
comments_count= card['mblog']['comments_count']
attitudes_count= card['mblog']['attitudes_count']
parse_dict['url'] =scheme
parse_dict['text'] =text
parse_dict['author'] =user
parse_dict['comments_count'] =comments_count
parse_dict['attitudes_count'] =attitudes_count
parse_dict_list.append(copy.deepcopy(parse_dict))
数据解析
最关键的一步,将协程对象添加到事件循环中,实现异步执行。
task_list = [] #定义一个任务列表
for data indata_list:
c= crawl(data) #调用协程,传参
task = asyncio.ensure_future(c) #创建任务对象
task_list.append(task) #将任务添加到列表中
loop = asyncio.get_event_loop() #创建事件循环
loop.run_until_complete(asyncio.wait(task_list)) #开启循环,并将阻塞的任务挂起
事件循环
以上部分就是整个爬虫的关键,剩下的数据写入(导出到excle)就直接放在源码中,不足之处,请大家指正!
importcopyimportaiohttpimportrequestsimportreimportasyncioimportjsonimportxlwtdefget_page():"""先用requests构造请求,解析出关键词搜索出来的微博总页数
:return: 返回每次请求需要的data参数"""data_list=[]
data={'containerid': '100103type=1&q={}'.format(kw),'page_type': 'searchall'}
resp= requests.get(url=url, headers=headers, params=data)
total_page= resp.json()['data']['cardlistInfo']['total'] #微博总数
#一页有10条微博,用总数对10整除,余数为0则页码为总数/10,余数不为0则页码为(总数/10)+1
if total_page % 10 ==0:
page_num= int(total_page / 10)else:
page_num= int(total_page / 10) + 1
#页码为1,data为当前data,页码不为1,通过for循环构建每一页的data参数
if page_num == 1:
data_list.append(data)returndata_listelse:for i in range(1, page_num + 1):
data['page'] =i
data_list.append(copy.deepcopy(data))returndata_list#async定义函数,返回一个协程对象
async defcrawl(data):"""多任务异步解析页面,存储数据
:param data: 请求所需的data参数
:return: None"""async with aiohttp.ClientSession() as f:#实例化一个ClientSession
async with await f.get(url=url, headers=headers, params=data) as resp: #携带参数发送请求
text = await resp.text() #await 等待知道获取完整数据
text_dict = json.loads(text)['data']['cards']
parse_dict={}for card intext_dict:if card['card_type'] == 9:
scheme= card['scheme']if card['mblog']['isLongText'] isFalse:
text= card['mblog']['text']
text= re.sub(r'<.>|\n+', '', text)else:
text= card['mblog']['longText']['longTextContent']
user= card['mblog']['user']['profile_url']
comments_count= card['mblog']['comments_count']
attitudes_count= card['mblog']['attitudes_count']
parse_dict['url'] =scheme
parse_dict['text'] =text
parse_dict['author'] =user
parse_dict['comments_count'] =comments_count
parse_dict['attitudes_count'] =attitudes_count
parse_dict_list.append(copy.deepcopy(parse_dict))definsert_data(file_name):"""将数据导出到excle中
:param file_name: 文件名
:return:"""wr= xlwt.Workbook(encoding='utf8')
table=wr.add_sheet(file_name)
table.write(0, 0,'原链接')
table.write(0,1, '正文')
table.write(0,2, '作者首页')
table.write(0,3, '评论数')
table.write(0,4, '点赞数')for index, data inenumerate(parse_dict_list):
table.write(index+ 1, 0, data['url'])
table.write(index+ 1, 1, data['text'])
table.write(index+ 1, 2, data['author'])
table.write(index+ 1, 3, data['comments_count'])
table.write(index+ 1, 4, data['attitudes_count'])
file_path= file_name + '.xls'wr.save(file_path)defmain(file_name):"""开启多任务循环
:return: None"""data_list= get_page() #接收data参数列表
task_list = [] #定义一个任务列表
for data indata_list:
c= crawl(data) #调用协程,传参
task = asyncio.ensure_future(c) #创建任务对象
task_list.append(task) #将任务添加到列表中
loop = asyncio.get_event_loop() #创建事件循环
loop.run_until_complete(asyncio.wait(task_list)) #开启循环,并将阻塞的任务挂起
insert_data(file_name)if __name__ == '__main__':
kw= input('关键词:')
headers={'user-agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2'}
url= 'https://m.weibo.cn/api/container/getIndex'parse_dict_list= [] #临时存放爬取的数据
main(kw)
完整代码
注意,由于微博的反爬机制,每次短时间的大量请求都会导致ip被短时间禁用,此处可以通过添加代理的方式来解决。我的想法是在页码解析部分添加代理池,随机选择代理,如果当前ip返回的状态码为200,则进行解析出页码,并将该ip携带到页面解析;若状态码不是200,则循环选择下一个ip。
-
python爬取微博关键词搜索博文
2021-03-17 17:58:38python爬取微博关键词搜索博文,只需要修改cookie和url参数 -
Scrapy实现微博关键词爬虫(爬虫结果写入mongodb)
2020-05-20 15:24:17爬取字段信息有: 关键词 微博ID 微博内容信息 微博赞的个数 微博转发个数 微博评论个数 转发微博的转发原因 微博日期 转发源ID 原微博的赞个数 原微博的评论个数 原微博的转发个数 存入数据库的ID值(可忽略) ...爬取字段信息有:
- 关键词
- 微博ID
- 微博内容信息
- 微博赞的个数
- 微博转发个数
- 微博评论个数
- 转发微博的转发原因
- 微博日期
- 转发源ID
- 原微博的赞个数
- 原微博的评论个数
- 原微博的转发个数
- 存入数据库的ID值(可忽略)
spiders文件夹下的microBlogSpider.py里这样写:
# -*- coding: utf-8 -*- import scrapy from scrapy import Spider, Request, FormRequest from scrapy.selector import Selector import datetime import random from blogSpider.items import microBlogItem, keyWordItem from blogSpider.items import keyWordItem import json class MicroblogspiderSpider(scrapy.Spider): name = 'microBlogSpider' allowed_domains = ['weibo.cn'] search_url = 'https://weibo.cn/search/mblog' # 默认100页 max_page = 100 myCookie = 'xxxxxxxxxxx' headers = { 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'Accept-Encoding': 'gzip, deflate, br', 'Accept-Language': 'zh-CN,zh;q=0.9', 'Cache-Control': ' max-age=0', 'Connection': ' keep-alive', 'Content-Type': ' application/x-www-form-urlencoded', 'Host': ' weibo.cn', 'Origin': ' https://weibo.cn', 'Upgrade-Insecure-Requests': ' 1', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36', } def start_requests(self): keyword = 罗志祥' startTime = '2020-05-01' endTime = '2020-05-02' start_time = datetime.datetime.strptime(startTime, '%Y-%m-%d') end_time = datetime.datetime.strptime(endTime, '%Y-%m-%d') # print(start_time) # print(end_time) cookie = {} for i in self.myCookie.split(';')[:-1]: cookie[i.split('=')[0]] = i.split('=')[1] while start_time <= end_time: currentTime = start_time # 处理时间格式 start = str(currentTime) end = str(currentTime) start_T = start[:start.index(' ')].replace('-', '') end_T = end[:end.index(' ')].replace('-', '') url = '{url}?hideSearchFrame=&keyword={keyword}&starttime={st}&endtime={et}&sort=hot'.format(url=self.search_url, keyword=keyword, st=start_T, et=end_T) yield scrapy.FormRequest( url, callback=self.parse_index, cookies=cookie, headers=self.headers, meta={ 'time': start_time, 'keyWord': keyword, } ) start_time += datetime.timedelta(days=1) def parse_index(self, response): if not response.body: return dateTime = response.meta['time'] keyWord = response.meta['keyWord'] # print(dateTime) cookie = {} for i in self.myCookie.split(';')[:-1]: cookie[i.split('=')[0]] = i.split('=')[1] url = '{url}&page={page}'.format(url=response.url, page=1) yield FormRequest( url, headers=self.headers, callback=self.getInfo, cookies=cookie, meta={ 'time': dateTime, 'keyWord': keyWord, } ) def getInfo(self, response): pageInfo = Selector(response) # print(response.body.decode('utf-8')) # allDiv是获取当前页面中所有含有微博信息的div标签 allDiv = pageInfo.xpath('//div[starts-with(@id,"M_")]') # print(allDiv) # print(len(allDiv)) # # 然后对所有DIV进行解析 for div in allDiv: # microBlogInfo = microBlogItem() # print(div) # print(type(div)) # 用来标注是否存入数据 flag = 0 microBlogInfo = microBlogItem() microBlogInfo['keyWord'] = response.meta['keyWord'] microBlogInfo['blogDate'] = str(response.meta['time']).split(' ')[0] microBlogInfo['microBlogId'] = div.css('a.nk ::text').extract()[0] microBlogInfo['originalBlogSupportNum'] = '' microBlogInfo['originalBlogCommentsNum'] = '' microBlogInfo['originalBlogForwardingNum'] = '' microBlogInfo['forwardingReason'] = '' microBlogInfo['fromBlogId'] = '' # print(microBlogInfo['microBlogId']) divs = div.xpath('div') divNum = len(divs) # print(divNum) if divNum == 3: # 包含3个DIV的类型为带图带转发微博 try: microBlogInfo['fromBlogId'] = div.xpath('div[1]/span[@class="cmt"]/a/text()').extract()[0] except: flag = 1 # print(microBlogInfo['fromBlogId']) if flag == 0: contents = div.xpath('div[1]/span[@class="ctt"]/text()').extract() microBlogInfo['contentInfo'] = '' for content in contents: content = "".join(content.split()) microBlogInfo['contentInfo'] += content # 去掉冒号 if microBlogInfo['contentInfo'][0] == ':': microBlogInfo['contentInfo'] = microBlogInfo['contentInfo'][1:] # print(microBlogInfo['contentInfo']) # 包含赞和转发数['赞[8322]', '原文转发[2927]'] originalInfo = div.xpath('div[2]/span[@class="cmt"]/text()').extract() oSNum = originalInfo[0][originalInfo[0].index('[')+1:originalInfo[0].index(']')] oFNum = originalInfo[1][originalInfo[1].index('[')+1:originalInfo[1].index(']')] # 包含评论数['原文评论[333]'] originalComment = div.xpath('div[2]/a[last()]/text()').extract() oCNum = originalComment[0][originalComment[0].index('[') + 1:originalComment[0].index(']')] # print(originalInfo) # print(oSNum) # print(oFNum) # print(originalComment) # print(oCNum) microBlogInfo['originalBlogSupportNum'] = oSNum microBlogInfo['originalBlogCommentsNum'] = oCNum microBlogInfo['originalBlogForwardingNum'] = oFNum lastDivInfo1 = div.xpath('div[3]/text()').extract() lastDivInfo2 = div.xpath('div[3]/*/text()').extract() microBlogInfo['forwardingReason'] = '' for info1 in lastDivInfo1: info1 = "".join(info1.split()) microBlogInfo['forwardingReason'] += info1 # print(microBlogInfo['forwardingReason']) for info2 in lastDivInfo2: info2 = "".join(info2.split()) if info2.startswith('赞['): microBlogInfo['numOfSupport'] = info2[info2.index('[')+1:info2.index(']')] elif info2.startswith('评论['): microBlogInfo['numOfComments'] = info2[info2.index('[')+1:info2.index(']')] elif info2.startswith('转发['): microBlogInfo['numOfForwarding'] = info2[info2.index('[')+1:info2.index(']')] else: continue # print('赞的个数:'+microBlogInfo['numOfSupport']) # print('评论个数:'+microBlogInfo['numOfComments']) # print('转发个数:'+microBlogInfo['numOfForwarding']) elif divNum == 2: firstSpan = div.xpath('div[1]/span[1]/@class').extract()[0] # print(firstSpan) # 第一个span的class=‘cmt’则证明是非带图转发微博 if firstSpan == 'cmt': try: microBlogInfo['fromBlogId'] = div.xpath('div[1]/span[@class="cmt"]/a/text()').extract()[0] except: flag = 1 if flag == 0: contents = div.xpath('div[1]/span[@class="ctt"]/text()').extract() microBlogInfo['contentInfo'] = '' for content in contents: content = "".join(content.split()) microBlogInfo['contentInfo'] += content # 去掉冒号 if microBlogInfo['contentInfo'][0] == ':': microBlogInfo['contentInfo'] = microBlogInfo['contentInfo'][1:] originalInfo = div.xpath('div[1]/span[@class="cmt"]/text()').extract() oSNum = originalInfo[len(originalInfo)-2][originalInfo[len(originalInfo)-2].index('[')+1:originalInfo[len(originalInfo)-2].index(']')] oFNum = originalInfo[len(originalInfo)-1][originalInfo[len(originalInfo)-1].index('[')+1:originalInfo[len(originalInfo)-1].index(']')] # print(oSNum) # print(oFNum) originalComment = div.xpath('div[1]/a[last()]/text()').extract() oCNum = originalComment[0][originalComment[0].index('[') + 1:originalComment[0].index(']')] # print(oCNum) microBlogInfo['originalBlogSupportNum'] = oSNum microBlogInfo['originalBlogCommentsNum'] = oCNum microBlogInfo['originalBlogForwardingNum'] = oFNum lastDivInfo1 = div.xpath('div[2]/text()').extract() lastDivInfo2 = div.xpath('div[2]/*/text()').extract() microBlogInfo['forwardingReason'] = '' for info1 in lastDivInfo1: info1 = "".join(info1.split()) microBlogInfo['forwardingReason'] += info1 # print(microBlogInfo['forwardingReason']) for info2 in lastDivInfo2: info2 = "".join(info2.split()) if info2.startswith('赞['): microBlogInfo['numOfSupport'] = info2[info2.index('[') + 1:info2.index(']')] elif info2.startswith('评论['): microBlogInfo['numOfComments'] = info2[info2.index('[') + 1:info2.index(']')] elif info2.startswith('转发['): microBlogInfo['numOfForwarding'] = info2[info2.index('[') + 1:info2.index(']')] else: continue # print('赞的个数:'+microBlogInfo['numOfSupport']) # print('评论个数:'+microBlogInfo['numOfComments']) # print('转发个数:'+microBlogInfo['numOfForwarding']) # ctt则为带图非转发微博 elif firstSpan == 'ctt': contents = div.xpath('div[1]/span[@class="ctt"]/text()').extract() microBlogInfo['contentInfo'] = '' for content in contents: content = "".join(content.split()) microBlogInfo['contentInfo'] += content # 去掉冒号 if microBlogInfo['contentInfo'][0] == ':': microBlogInfo['contentInfo'] = microBlogInfo['contentInfo'][1:] lastDivInfo = div.xpath('div[2]/a/text()').extract() # print(lastDivInfo) for info in lastDivInfo: info = "".join(info.split()) if info.startswith('赞['): microBlogInfo['numOfSupport'] = info[info.index('[') + 1:info.index(']')] elif info.startswith('评论['): microBlogInfo['numOfComments'] = info[info.index('[') + 1:info.index(']')] elif info.startswith('转发['): microBlogInfo['numOfForwarding'] = info[info.index('[') + 1:info.index(']')] else: continue # print('赞的个数:'+microBlogInfo['numOfSupport']) # print('评论个数:'+microBlogInfo['numOfComments']) # print('转发个数:'+microBlogInfo['numOfForwarding']) # 原创不带图微博 elif divNum == 1: contents = div.xpath('div/span[@class="ctt"]/text()').extract() microBlogInfo['contentInfo'] = '' for content in contents: content = "".join(content.split()) microBlogInfo['contentInfo'] += content # 去掉冒号 if microBlogInfo['contentInfo'][0] == ':': microBlogInfo['contentInfo'] = microBlogInfo['contentInfo'][1:] # print(microBlogInfo['contentInfo']) lastDivInfo = div.xpath('div/a/text()').extract() # print(lastDivInfo) for info in lastDivInfo: info = "".join(info.split()) if info.startswith('赞['): microBlogInfo['numOfSupport'] = info[info.index('[') + 1:info.index(']')] elif info.startswith('评论['): microBlogInfo['numOfComments'] = info[info.index('[') + 1:info.index(']')] elif info.startswith('转发['): microBlogInfo['numOfForwarding'] = info[info.index('[') + 1:info.index(']')] else: continue # print('赞的个数:'+microBlogInfo['numOfSupport']) # print('评论个数:'+microBlogInfo['numOfComments']) # print('转发个数:'+microBlogInfo['numOfForwarding']) if flag == 0: yield microBlogInfo
注意:mycookie填写你登录之后的cookie信息就行,具体操作步骤如下:
爬虫网站登录之后,F12打开浏览器网页详细界面,按照下面的点击,然后复制cookie粘贴到爬虫文件里即可
items.py里这样写:# -*- coding: utf-8 -*- # Define here the models for your scraped items # # See documentation in: # https://docs.scrapy.org/en/latest/topics/items.html import scrapy class microBlogItem(scrapy.Item): ''' 微博信息 ''' collection = 'microBlogData' keyWord = scrapy.Field() microBlogId = scrapy.Field() contentInfo = scrapy.Field() numOfSupport = scrapy.Field() numOfComments = scrapy.Field() numOfForwarding = scrapy.Field() forwardingReason = scrapy.Field() blogDate = scrapy.Field() fromBlogId = scrapy.Field() originalBlogSupportNum = scrapy.Field() originalBlogCommentsNum = scrapy.Field() originalBlogForwardingNum = scrapy.Field() id = scrapy.Field()
pipelines.py里这样写:
# -*- coding: utf-8 -*- # Define your item pipelines here # # Don't forget to add your pipeline to the ITEM_PIPELINES setting # See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html import pymongo class BlogspiderPipeline(object): def __init__(self): ''' 初始化mongodb的各项参数 :param mongoUrl: :param mongoPort: :param mongoDB: ''' self.mongoUrl = '127.0.0.1' self.mongoPort = 27017 self.mongoDB = 'SpiderTest' def open_spider(self, spider): ''' 开启爬虫时,链接数据库 :param spider: :return: ''' self.client = pymongo.MongoClient(self.mongoUrl, self.mongoPort) self.db = self.client[self.mongoDB] def process_item(self, item, spider): ''' 将数据写入数据库 :param item: :param spider: :return: ''' exist = self.db[item.collection].find({'microBlogId': item['microBlogId'], 'contentInfo': item['contentInfo'], 'blogDate': item['blogDate']}).count() if exist == 0: count = self.db[item.collection].count() item['id'] = count + 1 self.db[item.collection].insert_one(dict(item)) return item def close_spider(self, spider): ''' 关闭爬虫,关闭数据库 :param spider: :return: ''' self.client.close()
接下来,执行爬虫就可以啦!
-
《Python实用爬虫案例》练习3:使用requests和re库进行微博关键词爬虫并保存转赞评数据
2021-12-13 11:26:03爬取目标: 以“气候问题”为关键词爬取微博移动端网页相关博文并保存对应博文转赞评数据;相关库名:requests/re/panda/time -
微博关键字爬虫代码
2019-03-05 12:48:14根据关键字,起始时间,和天数自动抓取时间段内的微博,包括微博id ,用户id ,时间,vip,微博内容,转发信息,转发信息转发数和评论数,并写入excel表格。 -
微博任意关键词爬虫——使用selenium模拟浏览器
2019-04-03 15:29:12欢迎关注公众号:老白和他的爬虫 1.初识selenium 简单通过一些基础操作来熟悉一下selenium,在此之前你需要下载一个谷歌驱动,我帮你下载好了,公众号回复“20190403”获取驱动及今日份代码。 打开浏览器... -
关键词爬虫用户爬虫微博爬虫.zip
2021-11-08 14:21:571,增加了关键词爬虫,可以根据设置的关键词列表获取近期有关的微博内容(默认为50页),爬取的字段符合该项目其他功能的要求。 2,爬取的逻辑为,关键词到微博到评论到用户关系,将原来的本地CSV读取改为数据库操作... -
微博关键词爬取.py
2019-09-11 11:25:43该程序是根据微博中关键词的抓取,整个过程都包含注释内容。 -
Scrapy 新浪微博搜索爬虫
2020-12-24 18:30:28微博高级搜索可能你经常有这样的需要,比如最近有热度的事件兴起,你要抓取几月几号到几月几号这段时间,提及到某个关键词的微博。这其实是一个非常刚性的需求,这就要采用微博的高级搜索来完成了。本文采用 微博... -
爬虫实践-微博关键词搜索抓取
2018-05-15 17:05:00关键词: 1.终于离婚了 2.提离职 ...微博关键词抓取终于离婚了 微博关键词抓取提离职 微博关键词抓取相亲对象 微博关键词抓取给我的教训 转载于:https://www.cnblogs.com/aeip/p/9041892.html... -
python微博爬虫——使用selenium爬取关键词下超话内容
2021-02-04 17:13:35%d, n值到5说明已无法解析出新的微博" % (len(elems),n)) after = len(elems) if after > before: n = 0 if after == before: n = n + 1 if n == 5: print("当前关键词最大微博数为:%d" % after) insert_data(elems... -
python 微博爬虫之关键词检索
2019-06-11 17:22:36= None :#要注意微博分长文本与文本,较长的文本在文本中会显示不全,故我们要判断并抓取。 weibo['longText'] = item.get('longText').get('longTextContent') else: weibo['longText'] =None print(weibo['... -
爬虫实战 | 用Python爬取指定关键词的微博~
2021-06-17 00:23:36前几天学校一个老师在做微博的舆情分析找我帮她搞一个用关键字爬取微博的爬虫,再加上最近很多读者问微博爬虫的问题,今天小编来跟大家分享一下。01分析页面我们此次选择的是从移动端来对微博进行爬取... -
一个简单的python爬虫实践,爬取包含关键词的新浪微博
2021-02-04 05:57:17低速可控,简单粗暴,适合用来有针对性的搜集数据量不是很大的包含关键词的微博,每日可爬3-6万条。不过后来发现其实新浪有这个API,但是隐藏得很深,等我发现的时候这个爬虫已经写完了,抹泪:(さぁ、始めよう~说明... -
Python爬虫分析微博热搜关键词(代码已过时,仅供参考)
2021-02-18 22:02:20wordcloud.WordCloud(font_path=font,width=600,height=400) w.generate(result_str) w.to_file('微博热搜关键词词云.png') key = list(set(redata)) x,y = [],[] #筛选数据 for st in key: count = redata.count(st... -
基于Scrapy框架的微博评论爬虫实战
2021-12-11 00:22:06之前写过的微博爬虫是基于Requests的,今天来跟大家分享一下,基于Scrapy的微博爬虫应该怎么写。之前分享过一个Requests对微博评论的爬虫,已经对页面进行了全面的分析,本文主要... -
基于Python的新浪微博数据爬虫_周中华.pdf
2018-08-07 17:44:35为了快速地获取到海量微博中的数据,根据微博网页的特点,提出了一种基于Python爬虫程序设计方法.通过模拟登录新浪微博,实时抓取微博中指定用户的微博正文等内容;该工具利用关键词匹配技术,匹配符合规定条件的微博,并... -
基于Python的新浪微博数据爬虫
2020-11-26 04:27:18基于Python的新浪微博数据爬虫周中华,张惠然,谢江*【摘要】摘要:目前很多的社交网络研究都是采用国外的平台数据,而国内的新浪微博没有很好的接口方便研究人员采集数据进行分析。为了快速地获取到微博中的数据,... -
爬虫实战-抓取微博用户文本数据并生成词云(小白入门)
2020-12-21 15:20:14作为爬虫小白,代码偏向简单,大佬勿喷~ 本次使用语言:Python 本次使用库:requests、wordcloud、jieba 思路 通过尝试,在网页版微博死活找不出文本url(可能是能力有限),在移动端微博找到了,所以推荐大家爬取...