微博爬虫一(Selenium)

背景

  1. 一般企业做舆情分析,新浪微博是必不可少需要关注的。看看有没有负面消息尽早介入处理。人工查找筛选这些信息显然效率不够高,不够智能;

  2. 毕业以后,很少主动去关注母校的一些情况。借学习爬虫的机会,看看母校最近发生了什么。

目标

如下图,准备爬取母校微博账号【南京师范大学】近期发布的内容与互动情况。
爬取的数据包括:

  1. 微博发布的时间;
  2. 微博的文字内容;
  3. 图片信息(URL);
  4. 转发数量 ;
  5. 评论数量,评论人ID与评论内容;
  6. 点赞数量

在这里插入图片描述

探索

  1. 下拉网页,可以看到微博内容是Ajax动态加载的,细心探索,可以发现下拉3次即可完成整个页面的加载;
  2. 在页面底部点击“下一页”,会弹出登录验证信息,需要输入微博账号密码;
  3. 通过点击评论,可以看到每条微博下前排的评论人信息和评论内容。

爬虫实施

Step1:导入包,常量定义,初始化Selenium

from selenium.webdriver.common.action_chains import ActionChains
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from lxml import etree
import pandas as pd

url='https://weibo.com/njnusun?'
USER_NAME='xxxxxxxx'
PASSWORD='xxxxx'
driver = webdriver.Chrome(r"C:\Users\ThinkPad\AppData\Local\Google\Chrome\Application\chromedriver.exe")

这里给出了目标网址、微博用户名和密码(需要改成自己的账号信息哦),并打开了谷歌浏览器

Step2:打开目标网页,调整屏幕

driver.get(url)
time.sleep(2)
driver.maximize_window()   #窗口最大化

在这里插入图片描述
此时,Selenium已控制浏览器进入目标网页,不过是游客状态,未登录

Step3:模拟登陆:

在这里插入图片描述

  1. 使用xpath定位右上角登陆并模拟点击;
  2. 定位到账号输入框,模拟输入USER_NAME ;
  3. 定位到密码输入框,模拟输入PASSWORD;
  4. 定位到登陆按钮,模拟点击登陆
代码如下:
#设置显示等待,直到右上方登陆按钮可以点击
wait=WebDriverWait(driver,10)
wait.until(EC.presence_of_element_located((By.XPATH,'//a[@node-type="loginBtn"]')))
#定位到登陆按钮,点击
driver.find_element_by_xpath('//a[@node-type="loginBtn"]').click()

#设置显示等待,直到弹出登录对话框并且可点击登录
wait=WebDriverWait(driver,10)
wait.until(EC.presence_of_element_located((By.XPATH,'//a[@node-type="submitBtn"]')))

#模拟输入微博账号密码
driver.find_element_by_xpath('//input[@node-type="username"]').send_keys(user_name)
time.sleep(2)
driver.find_element_by_xpath('//input[@node-type="password"]').send_keys(password)
time.sleep(2)
driver.find_element_by_xpath('//a[@node-type="submitBtn"]').click()

Step4:处理Ajax加载,模拟执行JavaScript,下拉到底3次后网页即可全部加载出来

#将滚动条移动到页面的底部(重复3次)
js="var q=document.documentElement.scrollTop=100000"  
for i in range(3):   
    driver.execute_script(js)  
    time.sleep(3)

Step5:提取日期、文本、图片URL、转发数、评论数、点赞数等信息

以第一条微博为例:

date=driver.find_element_by_xpath('//div[@action-data="cur_visible=0"][1]/div/div[@class="WB_detail"]/div[2]/a').get_attribute('title')
text=''.join(tuple(driver.find_element_by_xpath('//div[@action-data="cur_visible=0"][1]/div/div[@class="WB_detail"]/div[4]').text.strip()))
image=''.join(driver.find_element_by_xpath('//div[@action-data="cur_visible=0"][1]/div/div[@class="WB_detail"]/div[6]//img[1]').get_attribute('src').strip())
forward=driver.find_element_by_xpath('//div[@action-data="cur_visible=0"][1]/div[2]//li[2]//em[2]').text
comment=driver.find_element_by_xpath('//div[@action-data="cur_visible=0"][1]/div[2]//li[3]//em[2]').text
like=driver.find_element_by_xpath('//div[@action-data="cur_visible=0"][1]/div[2]//li[4]//em[2]').text

结果如下:

在这里插入图片描述

Step6:提取每条微博的评论人ID与评论内容

1. 获取评论内容必须要点击评论按钮;
2. 评论按钮可点击的条件是该按钮在当前页面上可见

#定位到需要爬取评论内容的微博,使得评论按钮可见可点击
comment_button = driver.find_element_by_xpath('//div[@action-data="cur_visible=0"][1]/div/div[@class="WB_detail"]/div[6]//img')
driver.execute_script("arguments[0].scrollIntoView();", comment_button)
time.sleep(3)
#模拟点击评论,将评论内容展开
driver.find_element_by_xpath('//div[@action-data="cur_visible=0"][1]/div[2]//li[3]//em[2]').click()
time.sleep(3)

#获取网页源代码,解析得到评论人ID
page_source=driver.page_source
html=etree.HTML(page_source) 
comment_id=html.xpath('//div[@action-data="cur_visible=0"][1]//div[@node-type="replywrap"][1]/div[@class="WB_text"][1]/a[1]/@usercard')

#解析得到评论内容,和ID拼接起来
user_comment=''
for j in range(len(comment_id)):
    comments=''.join(html.xpath('//div[@action-data="cur_visible=0"][1]//div[{}]/div[@node-type="replywrap"][1]/div[@class="WB_text"][1]/text()'.format(j+1))).strip()
    user_comment+=comment_id[j]+comments+'\n'

代码封装

from selenium.webdriver.common.action_chains import ActionChains
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from lxml import etree
import pandas as pd

def open_url(url):    
    driver.get(url)
    time.sleep(2)
    driver.maximize_window()  #窗口最大化

def login(user_name,password):
    ##设置显示等待,直到右上方登陆按钮可以点击
    wait=WebDriverWait(driver,10)
    wait.until(EC.presence_of_element_located((By.XPATH,'//a[@node-type="loginBtn"]')))
    
    #定位到登陆按钮,点击
    driver.find_element_by_xpath('//a[@node-type="loginBtn"]').click()
    
    #设置显示等待,直到弹出登录对话框并且可点击登录
    wait=WebDriverWait(driver,10)
    wait.until(EC.presence_of_element_located((By.XPATH,'//a[@node-type="submitBtn"]')))
    
    #模拟输入微博账号密码
    driver.find_element_by_xpath('//input[@node-type="username"]').send_keys(user_name)
    time.sleep(2)
    driver.find_element_by_xpath('//input[@node-type="password"]').send_keys(password)
    time.sleep(2)
    driver.find_element_by_xpath('//a[@node-type="submitBtn"]').click()

#将滚动条移动到页面的底部(重复3次)
def tobottom(times):
    js="var q=document.documentElement.scrollTop=100000"  
    for i in range(times):   
        driver.execute_script(js)  
        time.sleep(3)

#将滚动条移动到页面的顶部
def totop():
    js="var q=document.documentElement.scrollTop=0"  
    driver.execute_script(js)  
    time.sleep(3) 

#解析
def parse_item():
    page_source0=driver.page_source
    html0=etree.HTML(page_source0)
    items=html0.xpath('//div[@action-data="cur_visible=0"]')
    for i in range(1,len(items)+1,1):
        result={}
        date=driver.find_element_by_xpath('//div[@action-data="cur_visible=0"][{}]/div/div[@class="WB_detail"]/div[2]/a'.format(i)).get_attribute('title')
        text=''.join(tuple(driver.find_element_by_xpath('//div[@action-data="cur_visible=0"][{}]/div/div[@class="WB_detail"]/div[4]'.format(i)).text.strip()))
       
        try:
            image=''.join(driver.find_element_by_xpath('//div[@action-data="cur_visible=0"][{}]/div/div[@class="WB_detail"]/div[6]//img[1]'.format(i)).get_attribute('src').strip())
        except:
            image=''
        
        try:
            forward=driver.find_element_by_xpath('//div[@action-data="cur_visible=0"][{}]/div[2]//li[2]//em[2]'.format(i)).text
        except:
            forward=''
        
        try:
            comment=driver.find_element_by_xpath('//div[@action-data="cur_visible=0"][{}]/div[2]//li[3]//em[2]'.format(i)).text
        except:
            comment=''
        
        try:
            like=driver.find_element_by_xpath('//div[@action-data="cur_visible=0"][{}]/div[2]//li[4]//em[2]'.format(i)).text
        
        except:
            like=''
            
        #定位评论    
        try:
            #定位到需要爬取评论内容的微博,使得评论按钮可见可点击
            comment_button = driver.find_element_by_xpath('//div[@action-data="cur_visible=0"][{}]/div/div[@class="WB_detail"]/div[6]//img'.format(i))
            driver.execute_script("arguments[0].scrollIntoView();", comment_button)
            time.sleep(3)
            
            #模拟点击评论,将评论内容展开
            driver.find_element_by_xpath('//div[@action-data="cur_visible=0"][{}]/div[2]//li[3]//em[2]'.format(i)).click()
            time.sleep(3)
            
            #获取网页源代码,解析得到评论人ID
            page_source=driver.page_source
            html=etree.HTML(page_source) 
            comment_id=html.xpath('//div[@action-data="cur_visible=0"][{}]//div[@node-type="replywrap"][1]/div[@class="WB_text"][1]/a[1]/@usercard'.format(i))

            #解析得到评论内容,和ID拼接起来
            user_comment=''
            for j in range(len(comment_id)):
                comments=''.join(html.xpath('//div[@action-data="cur_visible=0"][{}]//div[{}]/div[@node-type="replywrap"][1]/div[@class="WB_text"][1]/text()'.format(i,j+1))).strip()
                user_comment+=comment_id[j]+comments+'\n'
        except:
            user_comment=''
        
        #使用生成器返回数据
        result['date']=date
        result['text']=text
        result['image']=image
        result['forward']=forward
        result['comment']=comment
        result['user_comment']=user_comment
        yield result
            
#翻页
def next_page():
    next_page=driver.find_element_by_xpath('//a[@class="page next S_txt1 S_line1"]')
    next_page.click()

if __name__ == '__main__':
    url='https://weibo.com/njnusun?'#网页入口
    USER_NAME='xxxxx'         #微博账号
    PASSWORD='xxxxx'             #微博密码
    driver = webdriver.Chrome(r"C:\Users\ThinkPad\AppData\Local\Google\Chrome\Application\chromedriver.exe")
    
    #设置需要爬取的页数
    PAGES=3
    results=[]
    open_url(url)
    time.sleep(5)
    login(USER_NAME,PASSWORD)
    for i in range(PAGES):
        time.sleep(5)
        tobottom(3)
        time.sleep(3)
        totop()
        result=parse_item()
        for item in result:
            results.append(item)
            print(item)
        next_page()
        time.sleep(3)
  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!对于使用Selenium进行微博爬虫,您可以按照以下步骤进行操作: 1. 安装Selenium:您可以通过pip安装Selenium库,命令如下: ``` pip install selenium ``` 2. 下载WebDriver:Selenium需要与浏览器的驱动程序配合使用,您可以根据您使用的浏览器版本下载相应的驱动程序。比如,如果您使用的是Chrome浏览器,可以下载ChromeDriver。 3. 配置WebDriver:将下载好的WebDriver添加到系统的PATH环境变量中,以便Selenium能够找到它。 4. 编写爬虫代码:下面是一个简单的示例代码,演示如何使用Selenium登录微博并抓取页面内容: ```python from selenium import webdriver from selenium.webdriver.common.keys import Keys # 创建Chrome浏览器实例 driver = webdriver.Chrome() # 打开微博登录页面 driver.get("https://weibo.com/login.php") # 输入用户名和密码 driver.find_element_by_name("username").send_keys("your_username") driver.find_element_by_name("password").send_keys("your_password") # 模拟点击登录按钮 driver.find_element_by_css_selector(".W_btn_a").click() # 等待登录完成 driver.implicitly_wait(10) # 抓取页面内容 content = driver.page_source print(content) # 关闭浏览器实例 driver.quit() ``` 请注意,上述代码只是一个示例,并不能保证长期有效。微博可能会对爬虫进行限制或者更新登录页面的DOM结构,您需要根据实际情况针对性地进行修改和调试。 希望对您有所帮助!如有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值