利用http GET请求方式下载所有附件,当然可以自行对名称进行过滤
1、参数的获取
cookie:浏览器登陆QQ邮箱后,进入开发者选项,获取document.cookie
sid:登录QQ邮箱后,url地址中有sid值,格式如下
https://mail.qq.com/cgi-bin/frame_html?sid=*******&r=*******
2、确定请求地址
2.1、获取所有附件信息
点击附近收藏->全部附近,在开发者选项中查看请求地址
地址格式如下
https://mail.qq.com/cgi-bin/attachfolder?topmails=0&sid=*********&s=search&folderid=all&hflag=all&action=&page=0&t=attach_folder_list&searchmode=attach&advancesearch=0&perpage=40&loc=&isNeedToRedraw=true&ver=863972.1&cacheage=7200
其中需要个人的sid,还有个重要参数page,通过改变page达到遍历所有文件的目的。
2.2、获取附件名称和下载路径
在浏览器中访问上述地址可以看到如下信息
图中:
sDown:附件下载路径
最终下载路径:“https://mail.qq.com/”+sDown+"&loc=attachfolder,down,"+文件格式+"&"
sFileName:附件名称
获取了这些信息后就可以做批量下载了
代码如下
package main
import (
"fmt"
"golang.org/x/text/encoding/simplifiedchinese"
"io"
"io/ioutil"
"net/http"
"os"
"regexp"
"strings"
"sync"
)
const (
User_Agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36"
Cookie="*******"
)
type Charset string
const (
UTF8 = Charset("UTF-8")
GB18030 = Charset("GB18030")
)
var client=&http.Client{}
var wg=sync.WaitGroup{}
func main(){
sid:="********"
/*
获取文件下载地址,文件名称
*/
go func(){
for i:=20;i<24;i++ {
URL := fmt.Sprintf(`https://mail.qq.com/cgi-bin/attachfolder?topmails=0&sid=%s&s=search&folderid=all&hflag=all&action=&page=%d&t=attach_folder_list&searchmode=attach&advancesearch=0&perpage=40&loc=&isNeedToRedraw=true&ver=805371.1&cacheage=7200`,sid,i)
//%D7%F7%D2%B5
request, err := http.NewRequest("GET", URL, nil)
request.Header.Add("User-Agent", User_Agent)
request.Header.Add("Cookie", Cookie)
if err != nil {
panic(err)
}
response, err := client.Do(request)
if err != nil {
panic(err)
}
defer response.Body.Close()
context, err := ioutil.ReadAll(response.Body)
if err!=nil {
panic(err)
}
context_uft8 := convertByte2String(context, GB18030)
search(context_uft8)
}
defer close(jobs)
}()
wg.Add(4)
for i:=0;i<4;i++ {
go worker(jobs)
}
wg.Wait()
}
var jobs=make(chan []string,0)
func search(context string){
re:=regexp.MustCompile("sDown : \"(.*?)\"")
path := re.FindAllStringSubmatch(context, -1)
re=regexp.MustCompile("sFileName : \"(.*?)\"")
name := re.FindAllStringSubmatch(context, -1)
for i:=0;i<len(name);i++ {
jobs<-[]string{name[i][1],path[i][1]}
}
}
func worker(jobs chan []string){
for job:=range jobs {
download(job[0],job[1])
}
defer wg.Done()
}
func download(filename,path string){
fmt.Println("开始下载: ",filename)
temp:=strings.Split(filename,".")
URL:="https://mail.qq.com/"+path+"&loc=attachfolder,down,"+temp[1]+"&"
URL=strings.Replace(URL,"\\x26","&",-1)
request, err := http.NewRequest("GET", URL, nil)
if err != nil {
panic(err)
}
request.Header.Add("User-Agent", User_Agent)
request.Header.Add("Cookie", Cookie)
response,err:=client.Do(request)
if err != nil {
panic(err)
}
f, err := os.Create(filename)
if err != nil {
fmt.Println(err)
}
io.Copy(f, response.Body)
}
func convertByte2String(byte []byte, charset Charset) string {
var str string
switch charset {
case GB18030:
var decodeBytes,_=simplifiedchinese.GB18030.NewDecoder().Bytes(byte)
str= string(decodeBytes)
case UTF8:
fallthrough
default:
str = string(byte)
}
return str
}