0

Giải pháp lưu trữ với google driver

Hôm nay trong tầm hiểu biết của bản thân, mình xin chia sẻ về việc sử dụng google driver trong việc lưu trữ dữ liệu. Cụ thể hơn là ứng dụng crawl image từ trang web http://iphonewalls.net/. Tiến trình xử lý cơ bản sẽ là:

  1. Đọc Dom.
  2. Down image về Google driver local.
  3. Đồng bộ Google driver local với Google driver web.
  4. Đọc file từ Google driver web và trả lại link image cho app.

I. Đăng ký app

  • Trước tiên cần đăng ký một app trên môi trường developer google driver ở đây https://console.developers.google.com/apis/dashboard
  • Tiếp theo enable Google+ API và Google Drive API. Chúng ta sẽ cần G+ để lấy thông tin người dùng.
  • Trong mục Credentials click vào button configure consent screen để config app
  • Đăng ký thông tin project (thực tế chỉ cần name project)
  • Cuối cùng chúng ta tạo client ID, chọn loại ứng dụng cho web, sau đó nhập giá trị cho Authorized redirect URIs. => Và cuối cùng đây là kết quả: Ở đây chúng ta có Client ID, Client secret sẽ đại diện cho tài khoản google driver mà bạn sử dụng. Hơi nhiều hình ảnh cho một bài viết thì phải (yaoming). Giờ bắt đầu thôi nào!!!

II. Đọc Dom

Điều quan trọng nhất là chúng ta cần biết cấu trúc DOM của trang web chúng ta muốn crawl, ở trình độ của mình thì việc viết 1 tool nhận option là một trang web bất kỳ để crawl tự động là không thể... Nói về trang http://iphonewalls.net/. Nó cấu trúc theo các categories ảnh theo kiểu: origin_url/$category_name vì vậy ý tưởng của mình là sẽ tạo một mảng các categories rồi ghép với origin_url để lần lượt đọc từng page.

'categories_list' => ['abstract', 'animals', 'apple', 'architecture', 'brands', 'cars-bikes', 'close-ups',
    'food-drinks', 'funny', 'games', 'girls', 'guys', 'holiday', 'icon-tiles', 'illustrations', 'misc',
    'movies', 'music', 'nature', 'places', 'science-fiction', 'shelves', 'space', 'sports',
    'technology', 'textures', 'typography'
],

  • Sử dụng CURL để đọc toàn bộ DOM trên 1 page:
private function getDom($link)
{
    $ch = curl_init($link);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $content = curl_exec($ch);
    curl_close($ch);
    $dom = HtmlDomParser::str_get_html($content);
    return $dom;
}

Hàm getDOM sẽ trả lại toàn bộ DOM của 1 page. Khởi tạo:

$domConvert = $this->getDom($value);
  • Bây giờ Inspec để thấy được cấu trúc DOM của 1 page, VD page với categories là nature với link là http://iphonewalls.net/nature/ Mỗi page của 1 categories sẽ được phân trang bằng tag <div id="pagination"><ul><li><a></a></li></ul></div> Vì vậy việc đầu tiên là phải get được tổng số page của categories hiên tại
$domConvert->find('//*[@id="pagination"]/ul/li/a');
  • Tiếp theo loop qua từng page để get DOM
$dom = $this->getDom($value."page/".strval($page)."/");

Với mỗi page sẽ find tất cả các thẻ img theo query:

$dom->find('//*[@id="wallpapers"]/div/article[*]/figure/a/img'

Cuối cùng là việc xử lý đặt lại tên ảnh(nếu muốn), cấu hình file local để save:

foreach ($dom->find('//*[@id="wallpapers"]/div/article[*]/figure/a/img') as $link)
{
    $tmp = explode('.', $link->src);
    $format = end($tmp);
    $userImage = $key.'_'. $count .'.' .$format;
    $path = '/home/likewise-open/FRAMGIA/'.env('LOCAL_COMPUTER').'/Google_driver/'.$key.'/';
    $link_image = str_replace(" ","%20", preg_replace( "/-\d+x\d+/", "", $link->src));
    $ch = curl_init($link_image);
    $fp = fopen($path . $userImage, 'wb');
    curl_setopt($ch, CURLOPT_FILE, $fp);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    $result = curl_exec($ch);
    curl_close($ch);
    fclose($fp);
    $count++;
}

Ở trên mình có lưu đặt tên thư mục và tên categories đồng nhất để tiện xử lý. Sau bước này chúng ta đã có được các thư mục chứa ảnh trên google driver local, việc đồng bộ hóa là của GOOGLE Đây là những gì mình có, khoảng gần 10K ảnh của web này:

III. Đọc file từ Google driver web

Sau khi đã có toàn bộ ảnh chứa trên google driver, chúng ta sẽ xử lý việc đọc ảnh ngược lại để trả lại api cho app

  • Trước tiên phải config các biến như CLIENT_ID, CLIENT_SECRET, REDIRECT_URL đã nhận được ở mục I trong .env
SESSION_DRIVER=file
APP_TITLE=Driver
APP_TIMEZONE="Asia/Ho_Chi_Minh"
GOOGLE_CLIENT_ID="xxxxxxxxxxxxxxxxxxxxxxxxxx"
GOOGLE_CLIENT_SECRET="xxxxxxxxxxxxx"
GOOGLE_REDIRECT_URL="http://localhost:8000/login"
GOOGLE_SCOPES="email,profile,https://www.googleapis.com/auth/drive"
GOOGLE_APPROVAL_PROMPT="force"
GOOGLE_ACCESS_TYPE="offline"
LOCAL_COMPUTER="nguyen.van.hien"
  • Tạo một class để khởi tạo Google Client và Google Driver
class Googl
{
  public function client()
  {
    $client = new \Google_Client();
    $client->setClientId(env('GOOGLE_CLIENT_ID'));
    $client->setClientSecret(env('GOOGLE_CLIENT_SECRET'));
    $client->setRedirectUri(env('GOOGLE_REDIRECT_URL'));
    $client->setScopes(explode(',', env('GOOGLE_SCOPES')));
    $client->setApprovalPrompt(env('GOOGLE_APPROVAL_PROMPT'));
    $client->setAccessType(env('GOOGLE_ACCESS_TYPE'));

    return $client;
  }
  public function drive($client)
  {
    $drive = new \Google_Service_Drive($client);
    return $drive;
  }
}
  • Query để trả lại thông tin files:
$parameters = [
    'q' => $query,
    'orderBy' => 'modifiedTime',
    'fields' => 'nextPageToken, files(id, name, webViewLink, webContentLink)',
];

Các tham số:

  • q: chi tiết câu query. Bạn có thể xem thêm ở đây https://developers.google.com/drive/v3/web/search-parameters
  • orderBy: thứ tự sắp xếp.
  • fields: các trường mong muốn trả về sau câu truy vấn. Thường thì sau mỗi câu truy vấn có rất nhiều thông tin được trả về, và điều đó là không cần thiết. Ở đây chỉ các thông tin về id, name, link view và link download được trả về. Lưu ý: webContentLink là link ảnh để có thể sử dụng hiển thị ảnh trong app của bạn. Cuối cùng, function
$result = $this->drive->files->listFiles($parameters);

sẽ trả lại 1 object chứa đầy đủ các thông tin mà bạn cần. Tùy vào nhu cầu cho app mà bạn có thể lưu vào database hoặc show ảnh trực tiếp trên app của bạn bằng link webContentLink. Bài viết có chưá khá nhiều ảnh và code dễ gây khó chịu, các bạn thông cảm!!!

Github demo code: https://github.com/hiennv94/crawler_google_api Link tham khảo: https://www.sitepoint.com/is-laravel-good-enough-to-power-a-custom-google-drive-ui/


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí