python爬取微博某个用户的图片和文字信息分析

参考链接: https://www.cnblogs.com/dmyu/p/6034634.html

跑了一下给的代码发现不能得到所要的结果,于是分析了代码,在此记录一下分析过程:

爬取过程

  1. 在登录微博页面 微博手机版的时候获取cookie
  2. 然后使用python的request库请求http://weibo.cn/u/(your_weibo_id)?filter=1&page=(page_num) 的链接获取原创微博页页面数据,其中your_weibo_id为你想要爬取的微博id,filter=1表示只选择原创微博,删除该字段得到所有微博,page_num为第几页微博,例:人民日报: https://weibo.cn/u/2803301701?filter=1&page=1
  3. 然后使用BeautifulSoup库分析得到的html代码,得到微博文本信息以及图片的链接信息
  4. 然后保存文本,下载图片到本地

文字部分:

html代码中类名为“ctt”的span标签为文字部分

python爬取微博某个用户的图片和文字信息分析_第1张图片

图片部分:

1. 一开始请求的url中只显示一张图片,获取所有图片链接需要进入下一个链接

python爬取微博某个用户的图片和文字信息分析_第2张图片

2. 获取该url中html数据的“组图”的链接,再次使用request.get方法得到该链接的html代码,代码中包含有所有图片地址的链接。

python爬取微博某个用户的图片和文字信息分析_第3张图片

原代码链接:

https://www.cnblogs.com/dmyu/p/6034634.html

修改内容1.将代码中图片的地址协议从http换成https

  1. 由于微博页数仅一页的时候代码会报错 IndexError: list index out of range, 因为代码中不存在input的name属性为“mp”的标签,将其放入try代码中,如无此属性,让pagenum=1
  2. 将保存的文字信息写为.txt文件

将代码中16行的target_id换成用户的uid,17行的#your_cookie换成你的cookie就可以直接运行

#-*-coding:utf8-*-

import re
import string
import sys
import os
import urllib
import urllib.request
from bs4 import BeautifulSoup
import requests
import shutil
import time
from lxml import etree
import math

user_id = target_id    #目标用户id
c = "#your_cookie"	   #你的cookie

cookie = {
     "Cookie":c}
url = 'http://weibo.cn/u/%d?filter=1&page=1'%user_id
html = requests.get(url, cookies = cookie).content
print(u'user_id和cookie读入成功')
selector = etree.HTML(html)
# 获取微博页数
try:
    pageNum = (int)(selector.xpath('//input[@name="mp"]')[0].attrib['value'])
except:
    pageNum = 1
print('微博页数pageNum = ',pageNum)

result = ""          #保存文字内容
urllist_set = set()  #保存图片链接集
word_count = 1       #文字条数
image_count = 1      #图片数量
print(u'ready')
sys.stdout.flush()

times = 5  #分为times次访问,每次访问pageNum/times页,访问完一次使用sleep(n)暂停n秒,防止频繁访问被封
one_step = pageNum/times  
#每step访问的页数从页数i到页数j
for step in range(times):
    if step < times - 1:
        i = step * one_step + 1
        j =(step + 1) * one_step + 1
    else:
        i = step * one_step + 1
        j =pageNum + 1
    for page in range(math.floor(i), math.floor(j)):
        #获取url的html代码数据
        try:
            url = 'http://weibo.cn/u/%d?filter=1&page=%d'%(user_id,page)   
            lxml = requests.get(url, cookies = cookie).content     #使用request库带cookie参数访问url返回请求体为html页面内容
            #文字爬取
            selector = etree.HTML(lxml)                         
            content = selector.xpath('//span[@class="ctt"]')   #获取html数据中标签为span且其类名为ctt的文字部分
            #第一页前两个为网名和个性签名信息,从第三个开始为微博文字信息,result保存所有文字信息
            for each in content:
                text = each.xpath('string(.)')
                if word_count >= 3:
                    text = "%d: "%(word_count - 2) +text+"\n"
                else :
                    text = text+"\n\n"
                result = result + text
                word_count += 1
            print(page,'word ok')
            sys.stdout.flush()
            #图片链接爬取,构造的url中每条微博只显示一张图片,urllist为页面图片链接,urllist1为进入所有图片页面链接
            soup = BeautifulSoup(lxml, "lxml")
            urllist = soup.find_all('a',href=re.compile(r'^https://weibo.cn/mblog/oripic',re.I))
            urllist1 = soup.find_all('a',href=re.compile(r'^https://weibo.cn/mblog/picAll',re.I))
            #先将上个url中包含的图片链接放入集合urllist_set中,image_count +1
            for imgurl in urllist:
                imgurl['href'] = re.sub(r"amp;", '', imgurl['href'])
        #       print imgurl['href']
                urllist_set.add(requests.get(imgurl['href'], cookies = cookie).url)
                image_count +=1
            #进入所有图片页面的链接地址,得到新的html值,重新获取此链接下所有图片链接,加入urllist_set中,image_count +1
            for imgurl_all in urllist1:
                html_content = requests.get(imgurl_all['href'], cookies = cookie).content
                soup = BeautifulSoup(html_content, "lxml")
                urllist2 = soup.find_all('a',href=re.compile(r'^/mblog/oripic',re.I))
                for imgurl in urllist2:
                    imgurl['href'] = 'http://weibo.cn' + re.sub(r"amp;", '', imgurl['href'])
                    urllist_set.add(requests.get(imgurl['href'], cookies = cookie).url)
                    image_count +=1     
                image_count -= 1        #由于之前保存过这里的一张图片,所以image_count -1 
            print(page,'picurl ok')
        except:
            print(page,'error')
        print(page, 'sleep')
        sys.stdout.flush()
        time.sleep(60)    #每页的暂停时间
    print(u'正在进行第', step + 1, u'次停顿,防止访问次数过多')
    time.sleep(10)   #每个step的暂停时间
    
# 文件保存    
try:
    #保存文字信息到user_id.txt,保存图片链接信息到user_id_image.txt
    fo = open(os.getcwd()+"/%d.txt"%user_id, "w",encoding='utf-8')
    fo.write(result)
    word_path=os.getcwd()+'/%d'%user_id
    print(u'文字微博爬取完毕')
    link = ""
    fo2 = open(os.getcwd()+"/%s_image.txt"%user_id, "wb")
    for eachlink in urllist_set:
        link = link + eachlink +"\n"
    fo2.write(link)
    print(u'图片链接爬取完毕')
except:
    print(u'存放数据地址有误')
sys.stdout.flush()

#通过urllist_set中保存的图片链接下载图片
if not urllist_set:
    print(u'该用户原创微博中不存在图片')
else:
    #下载图片,保存在当前目录的weibo_img文件夹下
    image_path=os.getcwd()+'/weibo_image'
    if os.path.exists(image_path) is False:
        os.mkdir(image_path)
    x = 1
    for imgurl in urllist_set:
        temp= image_path + '/%s.jpg' % x
        print(u'正在下载第%s张图片' % x)
        try:
        # urllib.urlretrieve(urllib2.urlopen(imgurl).geturl(),temp)
            r = requests.get(imgurl, stream=True)
            if r.status_code == 200:
                with open(temp, 'wb') as f:
                    r.raw.decode_content = True
                    shutil.copyfileobj(r.raw, f)
        except:
            print(u"该图片下载失败:%s"%imgurl)
        x += 1
print(u'原创微博爬取完毕,共%d条,保存路径%s'%(word_count - 3,word_path))
print(u'微博图片爬取完毕,共%d张,保存路径%s'%(image_count - 1,image_path))

代码运行结果:
python爬取微博某个用户的图片和文字信息分析_第4张图片

你可能感兴趣的:(python,python,爬虫,微博,html)