用selenium实现对微博搜索数据的抓取



http://computational-communication.com/post/bian-cheng-gong-ju/2014-06-25-searching-weibo-with-selenium



1、模拟登录

  • 2、输入关键词搜索
  • 3、解析页面
  • 4、翻页
  • 5、组合

    作者:TT小和子 (计算传播学网站编辑)


    图源:www.businessinsider.com

    最近由于工作需要,编了一个小程序来实现某博搜索数据的抓取。为什么要写这个程序呢,因为某博开放的API接口里,并没有search这个接口,而这个接口在鄙人看来恰恰是最有价值的一个接口,可以返回定制关键词的所有微博(说所有也不准确,因为微博搜索的搜索限制最多返回一千条,所以往回追的话,最多只能抓到当天的1000条数据)。

    之前用其他现成的爬虫软件也能抓,但是多少都有点麻烦,禁JS啦,抓下来合并啦等,所以才下定决心自己用python写一个。

    在写代码前,设计了这个程序的功能和流程:
    1、模拟登录;
    2、输入关键词搜索;
    3、解析页面;
    4、翻页;
    5、重复3

    这个小程序用到的主要技术是selenium,一个web自动化测试工具,由此可见,我们想要做的,就是把人工一页页去翻,去粘贴复制的工作交给程序去做,原理上并没有啥高大上的。

    好,闲话少说,上菜!

    先把所有用到的包都放上面,后面都会用得上,除了selenium需要另外安装之外,其他都是python自带的包,安装selenium的方法,大家可以自己去搜索。

    from selenium import webdriver
    import selenium.webdriver.support.ui as ui
    from selenium.webdriver.common.action_chains import ActionChains
    from time import sleep
    from random import choice
    import re
    
    接下来使用selenium打开浏览器,我用的是Chrome,你也可以用Firefox:
    browser = webdriver.Chrome() # 打开谷歌浏览器
    wait = ui.WebDriverWait(browser,10) # 设定最长等待加载时间为10秒
    browser.get("http://s.weibo.com/") #打开微博搜索的地址

    打开页面之后,默认是没有登录的,所以我们需要模拟登陆

    1、模拟登录

    def login(username,password):
        wait.until(lambda browser: browser.find_element_by_xpath("//a[@node-type='loginBtn']"))#找到左上角登录按钮
        browser.find_element_by_xpath("//a[@node-type='loginBtn']").click() #点击登录按钮
        wait.until(lambda browser: browser.find_element_by_xpath("//input[@name='username']")) #等待登录页面出现
        user = browser.find_element_by_xpath("//input[@name='username']")
        user.clear() 
        user.send_keys(username) #输入用户名
        psw = browser.find_element_by_xpath("//input[@name='password']")
        psw.clear()
        psw.send_keys(password) #输入密码
        browser.find_element_by_xpath("//div[6]/a/span").click() #点击“登录”

    如果顺利的话,我们就登录微博了,接下来要输入我们要查询的关键词,进行搜索了。

    2、输入关键词搜索

    def search(searchWord):
        wait.until(lambda browser: browser.find_element_by_class_name("gn_name")) #等待用户名出现,确认登录成功
        inputBtn = browser.find_element_by_class_name("searchInp_form") #找到搜索框
        inputBtn.clear()
        inputBtn.send_keys(searchWord.strip().decode("gbk")) #输入搜索关键词
        browser.find_element_by_class_name('searchBtn').click() #点击“搜索”

    完成这一步之后,页面就会把第一页搜索结果展示出来。

    3、解析页面

    def gettext():
        content =[] #定义一个list,用来装一条条的微博
        wait.until(lambda browser: browser.find_element_by_class_name("search_page_M")) #等待翻页的元素出现
        texts = browser.find_elements_by_xpath("//dl[@action-type='feed_list_item']/dd[@class='content']/p[@node-type='feed_list_content']/em") #获取微博内容
        #print len(texts)
        for n in texts:
            try:
                emojiToDie = re.compile(u'[\U00010000-\U0010ffff]')
            except re.error:
                emojiToDie = re.compile(u'[\uD800-\uDBFF][\uDC00-\uDFFF]')
            mytext = emojiToDie.sub(u'', n.text) ##emojiToDie 顾名思义,是为了解决微博文本内容里的emoji图像而建立的一个正则表达式,我为什么这么恨emoji呢,因为你在往数据库里存,在解析它的时候,都会报错,所以干脆给它过滤掉
            content.append(mytext.encode("utf-8")) ##把每一条微博加到容器里
        return content

    OK,第一页处理完了,接下来怎么到第二页呢?

    4、翻页

    def nextPage():
        wait.until(lambda browser: browser.find_element_by_class_name("search_page_M")) #等翻页的元素出现
        if browser.find_elements_by_xpath("//ul[@class='search_page_M']") != None:
            nums = len(browser.find_elements_by_xpath("//ul[@class='search_page_M']/li"))
            pg = browser.find_element_by_xpath("//ul[@class='search_page_M']/li[%d]/a" %nums) #.text.encode("gbk") #找到“下一页”
            y = pg.location['y']+100 #找到“下一页”在页面的高度
            browser.execute_script('window.scrollTo(0, {0})'.format(y)) #滚动到“下一页”所在的行,必须让“下一页”出现在画面里,才能进行点击,这一点是血的教训
            ActionChains(browser).move_to_element(pg).click(pg).perform() #鼠标放到下一页上,点击,为啥不直接用click呢,因为会报错,说元素not clickable,泪的教训

    5、组合

    所有的功能都完成了,接下来要让它能循环地去抓取,我们还需要写个main()函数
    
    def main():
        login()
        search(Keyword)
        text =[]
        for i in range(0,10):
            text=text +gettext()
            sleep(choice([1,2,3,4]))##随机等待1或2或3或4秒,别抓太勤,微博会怀疑你是机器人的
            nextPage()

    小程序基本可以满足对微博搜索内容的抓取,但仍有需要完善的地方,比如如何实现代理IP,如何识别验证码,期待大神帮忙把它变得更丰满,在此抛砖引玉了~

    程序源代码:https://github.com/terry2tan/weibo_search

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值