文章目錄
- 一.準備作業
- 工具
- 二.思路
- 1.代碼整體思路
- 1.代碼詳細思路
- 三.分析介面
- 1.微博用戶搜索介面
- 2.用戶微博資料介面
- 四.撰寫爬蟲
- 五.得到資料
- 六.總結
最近博文瀏覽量每況愈下,為了拯救它,我放大招了,本次爬取新浪微博上用戶微博圖片(可以是小姐姐),用ip代理進行偽裝反爬,先來一張,
一.準備作業
工具
(1)chrome谷歌瀏覽器,分析介面
(2)python3.7,撰寫代碼
(3)你聰明的大腦,思考問題
二.思路
1.代碼整體思路
這里我用viso畫了兩個流程圖,便于大家理解代碼,我的代碼就是圍繞下圖的思路撰寫的,

1.代碼詳細思路

三.分析介面
微博介面的資料都是ajax異步加載的,
1.微博用戶搜索介面
通過我的分析和網上資料的參考,發現通過輸入name或者uid能夠回傳uid,screen_name等資料,
https://m.weibo.cn/api/container/getIndex?containerid=100103type%3D3%26q%3D【name】%26t%3D0
其中【name】為要檢索的用戶名或者用戶id,
2.用戶微博資料介面
此介面為用戶所有微博(原創,不包括轉載、回復),我們用此介面決議出圖片地址,
https://m.weibo.cn/api/container/getIndex?uid=【uid】&containerid=【containerid】
這里的uid為1中回傳結果中的uid,containerid為10760+uid的字串拼接,
介面的獲取參考了:
https://blog.csdn.net/weixin_43582101/article/details/96870665
道一聲感謝!
這里具體每個介面如何獲取,就不展開細說了,有時間的話會詳細展開說一下,
四.撰寫爬蟲
import json
import requests
import random
import re
import os
import time
import webbrowser
from lxml import etree
from concurrent.futures import ThreadPoolExecutor
#獲取&測驗代理Ip類
class GET_Proxy_and_Test(object):
def __init__(self):
self.base_url = 'https://www.kuaidaili.com/free/inha/{}/'
self.max_page=4
#獲取代理ip
def get_proxy(self):
print('第一次使用需要爬取ip代理...............')
headers = {
'Connection': 'keep-alive',
'Host': 'www.kuaidaili.com',
'Sec-Fetch-User': '?1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36',
}
result = list()
#爬取五頁ip作為代理
for i in range(1, self.max_page):
r = requests.get(self.base_url.format(i), headers=headers)
res = etree.HTML(r.text)
selector = res.xpath('//div[@id="list"]/table/tbody/tr')
for data in selector:
ip = data.xpath('./td[@data-title="IP"]/text()')
port = data.xpath('./td[@data-title="PORT"]/text()')
if ip:
proxy = ip[0] + ':' + port[0]
result.append(proxy)
print(proxy)
time.sleep(2)
aim_result=list(set(result))
return aim_result
#測驗代理ip
def test_proxy(self,ip_proxy):
print(f'正在測驗【{ip_proxy}】..............')
headers = {
'Accept-Language': 'zh-CN,zh;q=0.9',
'Cache-Control': 'max-age=0',
'Connection': 'keep-alive',
'Host': 'icanhazip.com',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36'
}
test_url = 'http://icanhazip.com/'
proxies = {
'HTTP': ip_proxy,
'HTTPS': ip_proxy
}
try:
r = requests.get(test_url, headers=headers, timeout=10, proxies=proxies)
res = r.text
if res:
self.save_to_txt(ip_proxy)
except:
pass
#寫入檔案
def save_to_txt(self,data):
aim_file='ip_proxy.txt'
with open(aim_file, 'a')as f:
f.write(data + '\n')
f.close()
#微博圖片爬取類
class WeiBo_Spider(object):
def __init__(self):
print('開始爬取微博圖片..............')
print('---------------------------------------------------------------------------------')
self.headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4252.0 Safari/537.36'
}
self.proxy_file='ip_proxy.txt'
self.path = aim_disk + ':\weibodownload\\'
#產生隨機代理ip
def get_ip(self):
with open(self.proxy_file,'r')as f:
iplist=f.readlines()
proxy = random.choice(iplist)
return proxy.strip()
def getHTMLText(self,url):
try:
r = requests.get(url, timeout=30)
r.raise_for_status()
r.encoding = 'utf8'
return r.text
except:
return ""
#獲取uid構造containerid
def getuid(self,name):#獲取uid構造containerid
url = f"https://m.weibo.cn/api/container/getIndex?containerid=100103type%3D3%26q%3D{name}%26t%3D0"
html = self.getHTMLText(url)
_json = json.loads(html)
try:
user = _json['data']['cards'][1].get('card_group')[0].get('user')
"""
2020-12-18在此改進,直接呼叫微博ajax介面,
檢索用戶資訊,回傳用戶id uid以及用戶名screen_name
"""
user_name = user.get('screen_name')
user_id = user.get('id')
start_url = 'https://m.weibo.cn/api/container/getIndex?containerid=107603' + str(user_id) # containerid=107603+uid
self.path=self.path+'\\'+user_name+f'_{user_id}'
return start_url
except:
print('沒有檢索到該用戶!請嘗試!')
return ""
#決議圖片地址
def getpics(self,base_url):
i=1
while True:
url = base_url+'&page={}'.format(i)
choice=self.get_ip()
print(f'系統選擇了:{choice}作為代理IP')
r=requests.get(url,headers=self.headers,proxies={'http':choice})
_json=json.loads(r.text)
items=_json["data"]["cards"]
flag=_json['ok']
if flag==1:#爬取資料標志
for v in items:
picslist=v.get('mblog')
if picslist is not None:
aims=picslist.get('pics')
if aims !=None:
for aim in aims:
img_url=aim['large']['url']
yield img_url
print('第',i,'頁爬完了...............')
else:
print('爬取結束!在第[',i,']頁終止,地址為:',url)
webbrowser.open(url)
os.system("pause")
break
i+=1
#下載圖片
def download(self,url):
filename=url.split('/')[-1]
filename=filename[10:]
r=requests.get(url,headers=self.headers)
try:
os.makedirs(self.path)
except:
pass
with open(self.path+'\\'+filename,'wb')as f:
f.write(r.content)
print(f'{filename}下載完成..............')
#程式入口,防止代碼冗余
def entrance(user_name):
pool=ThreadPoolExecutor(max_workers=4)
if not os.path.exists('ip_proxy.txt'):
proxy_spider = GET_Proxy_and_Test()
proxies = proxy_spider.get_proxy()
for proxy in proxies:
pool.submit(proxy_spider.test_proxy, proxy)
pool.shutdown()
print('IP代理爬取、測驗完成!..............')
spider = WeiBo_Spider()
start_url = spider.getuid(user_name)
for img_url in spider.getpics(start_url):
spider.download(img_url)
def main():
while True:
global key
global aim_disk
print('---------------------------------------------------------------------------------')
judge = input('請輸入博主大名或者用戶id:')
print('---------------------------------------------------------------------------------')
if re.match('\d{10}|[\u4E00-\u9FA5]+',judge):#匹配uid(規定為長度為10的數字)或者全中文
aim_disk = input('保存到磁盤:')
print('---------------------------------------------------------------------------------')
entrance(judge)
break
else:
print('輸入資訊有誤!請檢查!')
continue
if __name__=='__main__':
main()
五.得到資料
程式正常運行結束退出,打開檔案夾查看,


我將這個腳本打包成exe放在
https://wws.lanzous.com/iriWTjp6uwh
六.總結
- 本次爬取了微博照片,使用了ip代理來規避微博的反爬,所有圖片均為高清原圖,經測驗,爬幾十、十幾G沒有問題的,穩定性還是不錯的,最后打包成了exe可執行檔案,圖源水印,在此僅作舉例,請勿用于商業用途,思路、代碼方面有什么不足歡迎各位大佬指正、批評!最后懇請大家給個免費的贊!

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/241019.html
標籤:python
