|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- import 'dart:convert';
- import 'dart:io';
-
- import 'package:dio/dio.dart';
- import 'package:dio_cookie_manager/dio_cookie_manager.dart';
- import 'package:zhiying_comm/util/taobao/goods_pic_model.dart';
- import 'package:zhiying_comm/zhiying_comm.dart';
-
- import 'package:cookie_jar/cookie_jar.dart';
- import 'package:convert/convert.dart';
- import 'package:crypto/crypto.dart';
-
- // 淘宝详情图抓取
- class TaobaoLoader {
- static Future<List<String>> loadImages(String id) async {
- return _loadImagesNew(id);
- }
-
- static Future<List<String>> _loadImages1(String id) async {
- String url =
- 'http://h5api.m.taobao.com/h5/mtop.taobao.detail.getdesc/6.0/?api=mtop.taobao.detail.getdesc&appkey=12574478&data={"type":"0","f":"TB1AsvbfnqWBKNjSZFx8qwpLpla","id":"${id.toString()}"}&dataType=json&jsv=2.4.11&sign=e93a97b7e9a9a459297f4e689051c895&t=1538180732308&type=json';
- Dio dio = Dio();
- Response response = await dio.get(url);
- // Logger.debug(response.data.toString());
- Map<String, dynamic> json = Map<String, dynamic>.from(response.data);
- List<String> images = List();
- try {
- Map<String, dynamic> data = json['data'];
- List list = json['data']['wdescContent']['pages'];
- for (var item in list) {
- Logger.debug(item);
- RegExp exp = new RegExp("(?<=<img(.*?)>)(.*?)(?=</img>)");
- String image = exp.stringMatch(item.toString());
- if (image != null && image != '') {
- if (image.startsWith('//')) {
- images.add('http:' + image);
- } else if (image.startsWith('https://') || image.startsWith('http://')) {
- images.add(image);
- }
- }
- }
- } catch (err) {
- Logger.error(err);
- }
-
- return images;
- }
-
- ///方法说明:通过破解淘宝签名接口获取商品详情图片
- ///流程:第一次请求接口拿到cookie数据,拼接签名数据,第二次请求接口拿到图片连接数据
- ///方法地址
- ///https://darktiantian.github.io/%E8%AE%B0%E4%B8%80%E6%AC%A1%E6%B7%98%E5%AE%9D%E6%8E%A5%E5%8F%A3sign%E7%AD%BE%E5%90%8D%E7%A0%B4%E8%A7%A3/
- static Future<List<String>> _loadImagesNew(String id) async {
- String data = "{\"item_num_id\":\"" + id + "\"}";
- String time = DateTime.now().millisecondsSinceEpoch.toString();
- String appkey = "12574478"; //文章中使用的appkey
- String url = "https://h5api.m.taobao.com/h5/mtop.wdetail.getitemdescx/4.9/?jsv=2.4.11&appKey=$appkey&t=$time"
- "&sign=FAKE_SIGN_WITH_ANYTHING&api=mtop.wdetail.getItemDescx&v=4.9&type=jsonp&dataType=jsonp&callback=mtopjsonp2&data="
- "$data";
- Logger.log("url: " + url);
- Dio dio = Dio(BaseOptions(responseType: ResponseType.plain));
- var cookieJar = CookieJar();
- //dio绑定cookie管理器,以便第一次请求后获取cookie数据
- dio.interceptors.add(CookieManager(cookieJar));
- Map<String, dynamic> headers = new Map();
- headers['User-Agent'] =
- "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_4 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G35 Safari/601.1";
- Options options = new Options(headers: headers);
- //首次请求获取cookie
- await dio.get(url, options: options);
-
- String token = "";
- String _m_h5_tk = "";
- String enc_token = "";
- //根据第一次请求后返回的cookie拿到需要的数据
- List<Cookie> cookieList = cookieJar.loadForRequest(Uri.parse(url));
- for (int i = 0; i < cookieList.length; i++) {
- Cookie cookie = cookieList[i];
- Logger.log(cookie.name + " : " + cookie.value);
- if ("_m_h5_tk" == cookie.name) {
- _m_h5_tk = cookie.value;
- List<String> token_with_time = cookie.value.split("_");
- if (token_with_time.length > 0) {
- token = token_with_time[0];
- }
- }
- if ("_m_h5_tk_enc" == cookie.name) {
- enc_token = cookie.value;
- }
- }
-
- //设置第二次请求的cookie数据
- Map<String, dynamic> headers2 = new Map();
- headers2['cookie'] = "_m_h5_tk=$_m_h5_tk; _m_h5_tk_enc=$enc_token;"
- "User-Agent=Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_4 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G35 Safari/601.1";
- Options options2 = new Options(headers: headers2);
-
- //设置签名
- String time2 = DateTime.now().millisecondsSinceEpoch.toString();
- String sign = token + "&" + time2 + "&" + appkey + "&" + data;
- String mySign = string2Md5(sign);
-
- //设置第二次请求的url
- String url2 = "https://h5api.m.taobao.com/h5/mtop.wdetail.getitemdescx/4.9/?jsv=2.4.11&appKey=$appkey&t=$time2"
- "&sign=$mySign&api=mtop.wdetail.getItemDescx&v=4.9&type=jsonp&dataType=jsonp&callback=mtopjsonp2&data="
- "$data";
-
- //进行第二次网络请求拿到图片数据
- Dio dio2 = Dio(BaseOptions(responseType: ResponseType.plain));
- Response response2 = await dio2.get(url2, options: options2);
- Logger.log(response2.data);
-
- //根据返回的数据,拼接图片链接数据
- String result2 = response2.data;
- String object = result2.substring(result2.indexOf("(") + 1, result2.length - 1);
- Logger.log(object);
- var json = jsonDecode(object);
- GoodsPicModel model = GoodsPicModel.fromJson(json);
- List<String> images = List();
- if (null != model.data.images && model.data.images.length > 0) {
- /**
- * images字段的数据,在前面拼接好https:就可以作为商品详情的图片链接使用了
- */
- List<String> Images = model.data.images;
- List<String> mPicList = [];
- for (String pic in Images) {
- if (pic.isNotEmpty) {
- if (pic.startsWith("http")) {
- mPicList.add(pic);
- } else {
- mPicList.add("https:" + pic);
- }
- }
- }
- Logger.log("mPicList图片:" + mPicList.length.toString() + "\n" + mPicList.toString());
- if (mPicList.length > 0) {
- return mPicList;
- }
- } else {
- if (null != model.data.pages && model.data.pages.length > 0) {
- /**
- * pages字段的数据,数组中可能有多张图片的链接数据,以<img></img>标签框起来的
- * 先去掉前面的<img>标签,再以</img>标签分割各个图片链接数据,
- * 最后每个数据拼接上https:就可以作为商品详情图片链接返回了
- * 经测试images字段和pages字段的数据是相同的,所以取一个字段的数据返回就可以了
- */
- List<String> pages = model.data.pages;
- List<String> mPicList = [];
- for (String pic in pages) {
- String pic1 = pic.replaceAll("<img>", "");
- List<String> pic2 = pic1.split("</img>");
- if (pic2.length > 0) {
- for (String s in pic2) {
- if (s.isNotEmpty) {
- if (s.startsWith("http")) {
- mPicList.add(s);
- } else {
- mPicList.add("https:" + s);
- }
- }
- }
- }
- }
- Logger.log("图片2:" + mPicList.length.toString() + "\n" + mPicList.toString());
- if (mPicList.length > 0) {
- return mPicList;
- }
- }
- }
-
- return images;
- }
-
- // md5 加密
- static String string2Md5(String data) {
- var content = new Utf8Encoder().convert(data);
- var digest = md5.convert(content);
- return hex.encode(digest.bytes);
- }
- }
|