吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 9247|回复: 15
收起左侧

[Python 转载] python爬去微博获得微博个人页面所有相关信息

  [复制链接]
4028574 发表于 2018-6-8 20:51
本帖最后由 4028574 于 2018-6-8 21:07 编辑

本帖是为了承诺上一贴  爬取微博
通过超找人名 选择对应的人名 进入进行所有内容的爬取 主要是 发布的消息 图片连接 视频连接 发布消息时的时间 以及设备 把这些信息全部保存下来  只获得当前页面 操作起来非常简单  应该很简单了
因为此次操作用的是浏览器模拟操作 不需要分析发包协议 只需要分析所有的页面内容即可  程序运行会自动打开火狐浏览器 自动进行响应操作 操作完成后 会自动保存文件  
如果有朋友会用数据库的 可以修改代码  更改为数据包保存  当前程序使用的是json保存在本地  不是特别好看 但是所有的内容 是全的   
本来准备使用csv保存的 但是因为编码问题 不是特别好弄 所以放弃 直接使用json格式保存  好了  废话不多说 直接开搞

开发环境:  kali Linux   python2.7  
IDE: pycharm
第三方模块: selenium BeautifulSoup
火狐浏览器 最好是最新版本 不然 可能会调用失败
geckodriver 驱动 python调用火狐需要使用的驱动程序  地址:https://github.com/mozilla/geckodriver/releases/      
正常来说 这个驱动下载下来需要添加环境变量 这个给个省事的解决方案  把这个驱动 直接放进python的script文件夹中即可  放入之后 用cmd直接打geckodriver 如果能出来下图这样 就说明配置成功  然后就可以直接开启程序了

这里之所以选择使用浏览器模拟操作 是因为 直接发包会有微博的人机检测  而且不是以.js为后缀的 所以他随时可能修改js的代码 这样可能会出现 这个帖子刚发出来没多久 js变了 大家就找不到新的值了 就陷入僵局 用这个模拟的方法 就完全不用顾忌他的js  因为浏览器会自动解析js  我们只管直接抓取 我们需要的页面内容即可  这样也降低了难度
1.png

说明一下 本程序是在kali linux下调试通过 没有任何问题  如果在win的控制台下操作出现问题 请自己想办法修改控制台的编码为utf-8 就不会有错误了
下面是成品图   因为是json格式 排版比较乱 所以最好是直接存入数据库  这样就比较好看点  这个的图截图不到位 因为比较长 后面还有图片的详细地址
2.png

好了 直接上代码  需要搜索谁就去搜索谁吧
代码中注释的地方是火狐的无头模式  如果有了解的朋友 可以直接尝试下
[Python] 纯文本查看 复制代码
#!/usr/bin/evn python
# -*- coding: utf-8 -*-

from urllib import quote,unquote
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from bs4 import BeautifulSoup
import json
from time import sleep
import re
import codecs

class Weibo(object):
    def __init__(self,url=""):
        self.url = url
        #firefoxoption = webdriver.FirefoxOptions()
        #firefoxoption.set_headless()
        #self.browser = webdriver.Firefox(firefox_options=firefoxoption)
        print("正在打开浏览器,请稍后...")
        self.browser = webdriver.Firefox()

    def GetPageSource(self,url,mate,callback):
        print("正在打开网页,请稍后...")
        self.browser.get(url)
        wait = WebDriverWait(self.browser,10)
        userInfo = wait.until(EC.presence_of_element_located(mate))
        return callback(self.browser.page_source)

    def GetUserList(self,url):
        print ("正在获得找人页面所有匹配到的信息,请稍后...")
        retUserList = []
        bs = BeautifulSoup(url,"lxml")
        userList = bs.select("#pl_user_feedList .list_person")
        for user in userList:
            userInfo = {
                "nickName":user.select(".person_name")[0].a['title'],
                "mainPage":"https:" + user.select(".person_name")[0].a['href'],
                "Address":user.select(".person_addr > span:nth-of-type(2)")[0].get_text(),
                "Card": user.select(".person_card")[0].get_text(strip=True) if user.select(".person_card") else "",
                "Num": " ".join(user.select(".person_num")[0].get_text().lstrip().split("\n")),
                "PersonInfo":re.sub("[\t\n]","",user.select(".person_info")[0].get_text())
            }
            retUserList.append(userInfo)
        return retUserList

    def GetPersonPageContent(self,url):
        print("正在或者个人页面信息,请稍后")
        bs = BeautifulSoup(url,"lxml")
        contentList = bs.select("div[node-type='feed_list'] > div[action-type='feed_list_item']")
        retPersonInfoList = []
        for i in xrange(len(contentList)) :
            try:
                contentInfo = {
                    "id": str(i+1),
                    "from":contentList[i].select(".WB_from")[0].get_text(strip=True),
                    "text":contentList[i].select(".WB_text.W_f14")[0].get_text(strip=True),
                    "videoOrImg":self.GetImageOrVideoPath(contentList[i].select(".WB_media_wrap")[0]) if contentList[i].select(".WB_media_wrap") else ""
                }
                retPersonInfoList.append(contentInfo)
            except:
                continue
        return retPersonInfoList


    def GetImageOrVideoPath(self,source):
            media = source.select(".WB_media_a")[0]
            url = media.select(".WB_video")
            if url:
                videoPath = unquote(unquote(url[0]["video-sources"][8:]))
                return videoPath
            else:
                try:
                    actionData = media["action-data"]
                    if actionData :
                        if "pic_ids" in actionData:
                            data = re.search("clear_picSrc=(.*?)&", actionData)
                            imageList = [ "https:%s"%(unquote(img)) for img in data.group(1).split(",")]
                            return ",".join(imageList)
                        else:
                            data = re.search("clear_picSrc=(.*?)$", actionData)
                            return "https:" + unquote(data.group(1))
                except KeyError as e:
                    imagePath = media.select(".WB_pic")[0].a.img["src"]
                    return imagePath


    def SavePersonInfo(self,filename,content):
        with codecs.open("./%s.json" % filename, "w+", "utf-8") as f:
            for i in content:
                f.write(json.dumps(i) + "\n")

    def run(self,url):
        userList = self.GetPageSource(url,(By.ID,"pl_user_feedList"),self.GetUserList)
        if userList:
            for i in xrange(len(userList)) :
                print ("%d:\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n"%(i+1,userList[i]["nickName"],userList[i]["mainPage"],userList[i]["Address"],userList[i]["Card"],userList[i]["Num"],userList[i]["PersonInfo"]))
        else:
            return -1
        while True:
            try:
                inputcontent = int(raw_input("请在上面输出的内容中选择需要的选项 1-%d: "%len(userList)))
                if inputcontent > 0 and inputcontent <= len(userList):
                    break
                print("请输入数字的范围 1 - %d "%len(userList))
            except:
                print("请输入数字的范围 1 - %d "%len(userList))
                continue
        self.browser.execute_script("window.open()")
        self.browser.switch_to_window(self.browser.window_handles[1])
        userInfo = self.GetPageSource(userList[inputcontent-1]["mainPage"],(By.CSS_SELECTOR,"div[node-type='feed_list']"),self.GetPersonPageContent)
        if userInfo :
            self.SavePersonInfo(userList[inputcontent-1]["nickName"],userInfo)

    def __del__(self):
        if self.browser.window_handles:
            for hand in self.browser.window_handles:
                self.browser.switch_to_window(hand)
                self.browser.close()

def main():
    name= raw_input("请输入需要搜索的名字 : ")
    name = quote(quote(name))
    url ="http://s.weibo.com/user/%s&Refer=index"%name
    weiboret = Weibo()
    weiboret.run(url)


if __name__ == '__main__':
    main()

免费评分

参与人数 4吾爱币 +4 热心值 +3 收起 理由
154675361 + 1 + 1 谢谢@Thanks!
锋范fast + 1 用心讨论,共获提升!
苏紫方璇 + 1 + 1 用心讨论,共获提升!
dotson + 1 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| 4028574 发表于 2018-6-11 10:58
154675361 发表于 2018-6-11 08:51
楼主,能告诉一下window下怎么设置编码吗,网上搜了一堆没用,谢谢了

可能是代码开头改一下 就可以了吧
#coding:utf-8
我也不知道 行不行 你可以试下
hycq120 发表于 2018-6-8 21:15
kk1212 发表于 2018-6-8 21:22
Dlan 发表于 2018-6-8 21:33
可以,我喜欢
Dlan 发表于 2018-6-8 21:35
我还是喜欢抓包,直接访问接口,再加上多IP
上官轩墨 发表于 2018-6-8 22:38
楼主这是要安装多少个库?,新手,没安装库,应该不能运行吧
154675361 发表于 2018-6-8 23:50
感谢楼主,拿走学习了,nice
chen4321 发表于 2018-6-9 07:03 来自手机
谢谢分享,学习了
servicelabs 发表于 2018-6-9 09:11
不错,直接copy保存了!
154675361 发表于 2018-6-11 08:51
楼主,能告诉一下window下怎么设置编码吗,网上搜了一堆没用,谢谢了
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-16 13:23

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表