webman_ad/app/event/TiktokAdsDetails.php
2024-12-17 21:11:21 +08:00

185 lines
7.9 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace app\event;
use app\model\TiktokAdsDetail;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use support\Db;
use QL\QueryList;
use support\Redis;
class TiktokAdsDetails
{
const userAgent = 'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36';
const url = 'https://library.tiktok.com/api/v1/items';
const type = 'tiktokadsdetails';
// const countries = ["AT", "BE", "BG", "HR", "CY", "CZ", "DK", "EE", "FI", "FR", "DE", "GR", "HU", "IS", "IE","IT", "LV", "LI", "LT", "LU", "MT", "NL", "NO", "PL", "PT", "RO", "SK", "SI", "ES", "SE", "CH", "TR", "GB"] ;
// const countries = ["GB", "BE"];
/**
* 每天爬取tiktok广告详情
* @return void
*/
public function update()
{
try {
$client = new Client([
//允许重定向
// 'allow_redirects' => true,
]);
$adIdCache = Redis::lPop(TiktokAds::type . 'AdsIds');
if (empty($adIdCache)) {
dump('获取AD id 异常:');
return;
}
$currentParams = ['ad_id' => $adIdCache,'action' => 'details'];
$environment = 'vvv';
$proxyIp = '103.122.176.175';
$proxyPort = '31186';
$proxyUser = 'B978321E';
$proxyPassword = '1EC4E3C7398F';
$proxyAuth = base64_encode($proxyUser . ":" . $proxyPassword);
$options = [
"headers" => [
'accept' => 'application/json, text/plain, */*',
'accept-language' => 'zh-CN,zh;q=0.9',
'content-type' => 'application/json',
'cookie' => 'cookie: _ttp=2ov8Fc4C2CaNscHJd90O9fMhlpE; _ga=GA1.1.1025820618.1731926196; FPID=FPID2.2.Bcgkp%2Fk%2Bbn5w5YeSMR9wd9VpNHJwTUpkkaEqSdCEa0w%3D.1731926196; FPAU=1.2.944915349.1731926193; FPLC=CfAlWGYPInwi1oHk0kTm68d0p21YS3UZ31sOR60H2uVC7A20NL46YHkF9z36OOlKC9XHODO2%2Biet2kk486i6SmO0TcqGntq1CbgwSqOH6f4ZES7jiHeI0mu82CKUVg%3D%3D',
'origin' => 'https://library.tiktok.com',
'priority' => 'u=1, i',
'referer' => 'https://library.tiktok.com/ads?region=AT&start_time=1731945600000&end_time=1732032000000&adv_name=&adv_biz_ids=&query_type=&sort_type=last_shown_date,desc',
'sec-ch-ua' => '"Google Chrome";v="131", "Chromium";v="131", "Not_A Brand";v="24"',
'sec-ch-ua-mobile' => '?0',
'sec-ch-ua-platform' => '"Windows"',
'sec-fetch-dest' => 'empty',
'sec-fetch-mode' => 'cors',
'sec-fetch-site' => 'same-origin',
'user-agent' => self::userAgent,
],
];
if($environment !== 'env') {
$options["headers"]["Proxy-Authorization"] = "Basic " . $proxyAuth;
$options["proxy"] = $proxyIp . ':' . $proxyPort;
}
$res = json_decode($client->request('Get', self::url.'/'.$currentParams['ad_id'].'/'.$currentParams['action'], $options)->getBody()->getContents(), true);
// dump($res);return; //调试点
if (empty($res['data']) || $res['code'] != 0) {
dump('更新tiktok Ads Details接口响应异常' . json_encode($res, JSON_UNESCAPED_UNICODE));
return;
}
$ad = $res['data'];
if( $ad['ad']['audit_status'] == 2 || empty( $ad['ad']['videos'])){
return; //审核不过或者没视频不采集
}
$imagesJson = is_array($ad['ad']['image_urls']) ? json_encode($ad['ad']['image_urls']):json_encode([]);
$targetingLocationJson = is_array($ad['targeting']['location']) ? json_encode($ad['targeting']['location']):json_encode([]);
$targetingAgeJson = is_array($ad['targeting']['age']) ? json_encode($ad['targeting']['age']):json_encode([]);
$targetingGenderJson = is_array($ad['targeting']['gender']) ? json_encode($ad['targeting']['gender']):json_encode([]);
// dump($rejection_info);
$insertData[$ad['ad']['id']] = [
'ad_id' => $ad['ad']['id'],
'ad_name' => $ad['ad']['name'],
'audit_status' => $ad['ad']['audit_status'],
'ad_type' => $ad['ad']['type'],
'first_shown_date' => $ad['ad']['first_shown_date'],
'last_shown_date' => $ad['ad']['last_shown_date'],
'estimated_audience' => $ad['ad']['estimated_audience'],
'spent' => $ad['ad']['spent'],
'impression' => $ad['ad']['impression'],
'show_mode' => $ad['ad']['show_mode'],
'sor_audit_status' => $ad['ad']['sor_audit_status'],
'image_urls' => $imagesJson,
'advertiser_name' => $ad['advertiser']['name'],
'adv_biz_ids' => $ad['advertiser']['adv_biz_ids'],
'registry_location' => $ad['advertiser']['registry_location'],
'sponsor' => $ad['advertiser']['sponsor'],
'targeting_location' => $targetingLocationJson,
'targeting_age' => $targetingAgeJson,
'targeting_gender' => $targetingGenderJson,
'target_audience_size' => $ad['targeting']['target_audience_size'],
'audience_type' => $ad['targeting']['audience'],
'interest' => $ad['targeting']['interest'],
'video_interactions' => $ad['targeting']['video_interactions'],
'creator_interactions' => $ad['targeting']['creator_interactions'],
];
if(isset($ad['ad']['videos']) && !empty($ad['ad']['videos'])) {
// 遍历 "videos" 数组
foreach ($ad['ad']['videos'] as $video) {
$insertData[$ad['ad']['id']]['video_url'] = $video['video_url'];
$insertData[$ad['ad']['id']]['cover_img'] = $video['cover_img'];
}
}
// dump($insertData);return;
if (empty($insertData)) return;
//开启事务
Db::beginTransaction();
//删除原来的旧数据
TiktokAdsDetail::query()->where('ad_id', $currentParams['ad_id'])->delete();
//添加新的数据
TiktokAdsDetail::query()->insert($insertData);
//redis缓存
Redis::set(self::type, json_encode($insertData, JSON_UNESCAPED_UNICODE));
//redis缓存 记录更新时间
$time = date('Y-m-d H:i:s');
Redis::set(self::type . 'time', $time);
//提交事务
Db::commit();
//销毁$res
unset($res);
dump(date('Y-m-d H:i:s') . '更新' . self::type . '成功');
} catch (GuzzleException|\Exception $exception) {
//回滚事务
Db::rollBack();
dump('更' . self::type . '的广告ID为 '.$currentParams['ad_id'].' 异常:' . $exception->getMessage());
dump($exception);
}
// } catch (ClientExceptionInterface $e) {
// // 捕获 4xx 错误
// dump( 'Client error: ' . $e->getMessage() . "\n");
// } catch (ServerExceptionInterface $e) {
// // 捕获 5xx 错误
// dump('Server error: ' . $e->getMessage() . "\n");
// } catch (TransportExceptionInterface $e) {
// // 捕获网络传输错误
// dump('Transport error: ' . $e->getMessage() . "\n") ;
// } catch (\Exception $e) {
// // 捕获所有其他错误
// dump('General error: ' . $e->getMessage() . "\n") ;
// }
}
}