เอาหล่ะ.. ขอย้อนเวลา กล่าวถึงความเป็นมาเป็นไปก่อนนิดนึง ..

เนื่องจากก่อนหน้านี้ เว็บ welovepro.com ของผม มี Tags ที่เพิ่มเข้ามากับข่าวเยอะมาก และซ้ำซ้อนกัน เช่นในหนึ่งข่าวมี .. “งานวันแม่“, “วันแม่” ซึ่งจริงๆมันรวมกันเป็นตัวเดียวก็พอ หรือเขียนผิดเป็น “านวันแม่” งอ งู หายไป อาจะเพราะ Copy มาไม่หมด … ซึ่ง 2 Case นี้เจอเยอะมาก!! อาจเพราะความเร่งรีบของคนที่ Add ข่าว ทำให้มันมีสิ่งที่เกิน หรือผิดพลาดไปบ้าง

และด้วยความรู้ด้าน SEO ของผมที่เท่ากับหางอึ่ง คิดว่ามันจะกลายเป็น Duplicate Content ในหน้า Tags ต่างๆ หรือเป็น Tag ที่ไม่ถูกต้อง … ผมจึงจัดการลบ Tag ที่ไม่จำเป็น หรือเขียนผิดออกไป โดยลืมคิดถึงผลลัพท์ที่ตามมา หรือวิธีป้องกันผลกระทบด้านอื่นๆที่จะตามมา !!!

ในความคิดผม ผมก็แค่ Generate Site Map ตัวใหม่ แล้ว Submit ขึ้นไปอีกที ก็น่าจะพอ …

แต่ผลที่เจอก็คือ!!

ถึงแม้จะ Submit Site Map ชุดใหม่ ที่ล้าง Tags ไปแล้ว แต่ Google ยังวิ่งตาม Site Map ตัวเก่าอยู่เรื่อยๆ.. ไม่เห็นมีวี่แววว่ามันจะมองแต่เฉพาะ Site Map ตัวใหม่ของผมซักที!! แถมยังมีพวกเว็บไซต์ต่างๆนาๆ ที่มา Copy Content ของผมไปแบบทั้งดุ้น แล้วมีแปะ Link มายัง Tag เก่าๆที่ผมลบทิ้งไปแล้วด้วย!! 

 

จะเป็นยังไงหล่ะทีนี้ … ใน Google Webmaster Tools ก็ฟ้องว่าไม่เจอ URL (Error 404) กันเป็นแถวซิฮะ!!!!!! ลบไปหลายร้อยถึงพัน Tag คิดดูว่าจะ Error เยอะขนาดไหน?

 

tags error 404

 

ซึ่งเท่าที่อ่านมา .. ก็มีหลายคนบอกกันว่า Google พูดว่า..  “Error 404 เนี่ยะ ไม่ได้กระทบ หรือทำให้เว็บคุณเสียหายแต่อย่างใด” แต่ทว่า.. การที่มีมันเยอะเกินไป มันอาจจะมองได้ว่าเว็บคุณไม่มีคุณภาพ และเป็นสาเหตุให้ Ranking ตกลงได้นะ !!

 

จริงๆ ทางแก้ที่ถูกต้องของเรื่อง Tags ซ้ำซ้อนนี้ ควรทำอย่างไร?

ในความคิดของผม (ซึ่งก็ไม่รู้หรอกนะว่าถูกมั้ย? ใครคิดว่าไม่ใช่ ไปหา Seach วิธีที่ถูกกันเอาเองละกันนะ) ก็คือ..

เราควรจะลบ Tag พวกนั้นทิ้งไป หรือแก้ไขให้มันเขียนให้ถูกต้องนั่นแหละถูกแล้ว .. แต่ว่าไม่ใช่ลบเฉยๆ !!!  คุณจะต้องทำ 301 redirect URL ของตัว Tag ที่ถูกลบ ไปยัง Tag ใหม่ที่ถูกต้อง และใช้งานได้!!!  เพื่อบอกให้ Google รู้ว่า .. ไอ้ Tag นี้อ่ะ มันไม่มีแล้วนะ แต่มันย้ายไปที่ใหม่ ไปดูซิ!!! ส่วนคนปกติธรรมดาอย่างเราๆ ก็จะไม่เจอหน้า 404 แล้ว แต่จะเจอหน้า Tag ที่ถูกต้องแทน!!

ปล. 301 redirect URL นี่ .. ไว้จะเอามาอธิบายในโอกาสต่อไป หรือจริงๆ Search หาเอาก็ได้ มีบอกเยอะแยะ ตาแป๊ะไก่

 

แล้ว ณ ตอนนี้.. ผมต้องทำอย่างไร?

จริงๆแล้ว ผมควรจะเขียนโปรแรม ดึงค่า Crawl Error มา แล้วเอาไปทำ 301 redirect อัตโนมัติ!! แต่เนื่องด้วยผมลบ Tag ไปเยอะมาก และจำไม่ได้ว่าลบอะไรไปมั่ง? .. รวมถึงไม่มีเวลามานั่งจับคู่ทีละตัว ว่า Tag ที่ผิดตัวนี้ จะไปคู่กับ Tag ที่ถูกตัวไหน?

ผมเลยต้องใช้วิธี Add Tag เหล่านั้นกลับเข้ามาก่อน.. เพื่อลด Error 404 ที่เจออยู่ จากนั้นค่อยๆทะยอยไปทำตัวจับคู่ Tag ต่างๆที่ผิดพลาด กับตัวที่ถูกทั้งหมด แล้วค่อยเขียนโปรแกรม สั่งให้มัน Redirect ให้ถูกที่ ก่อนจะลบมันทิ้งอีกที.. ทำทีเดียวเยอะๆ ไม่เหนื่อย..

 

แนวคิด / เครื่องมือที่ต้องใช้

  1. ไปดึง Crawl Error จาก Google Web Master Tools แล้วเลือกเอาส่วนที่เรา สามารถแก้ได้ด้วยโปรแกรมอัตโนมัติมาก่อน ในที่นี้คือ tag/xxxxx ที่เหลือ ก็ให้เก็บเป็น Log แจ้งเราให้เจ้าไปแก้ Manual เอาเอง ซึ่งโดยปกติดราสามารถเรียก API Google เหล่านี้ ผ่าน HTTP request ได้ตามสะดวกเลย .. แต่ผมชอใช้ libraries สำหรับเชื่อมต่อกับ Google APIs ที่เค้าทำมาให้แล้วมากกว่า!! ซึ่งก็มีหลายภาษา ทั้ง Java, Phyton, .NET, Java Script ฯ นู่นนี่ .. แต่ที่ผมถนัดที่สุดคือ และจะเอามาใช้งาน คือภาษา PHP (เลือก Download เอาได้ที่ https://developers.google.com/api-client-library/?hl=th)
  2. เมื่อดึง Error Log มาแล้ว ก็หาเฉพาะตัวที่เป็น Tag จากนั้นนำไป Search ใน WordPress หาข่าวหรือ Post ที่ใกล้เคียงกับ Tag นั้น แล้วจับยัด Tag นี้เข้าไป
  3. อันไหนเป็น Error ที่ยังทำอัตโนมัติไม่ได้ หรือยังไม่ได้เขียนโปรแกรมแก้ไขในส่วนนี้ ส่งเมล์มาแจ้งเรา ให้เข้าไปทำ Manual เอาเอง
  4. ตั้ง Crontab ให้มันทำทุกๆวัน

 

เริ่มต้นด้วยการ Create Google Project เพื่อเอา API Key และ พวก Client ID, Secret Key มาใช้งาน

คือถ้าเราจะแทบเชื่อมต่อกับ Products ของ Google ได้แทบจะทุกตัวแล้ว แต่ในการเชื่อมต่อ เราต้องมี Account ของ Google เพื่อจะได้ Create Project และเขียนโปรแกรมเชื่อมต่อกับ Products ต่างๆได้

เรื่องนี้ ถ้าจะให้มาอธิบายกัน ก็คงยาว เยอะ.. จนแยกได้เป็นอีกเรื่องหนึ่งเลย!! ดังนั้นใน Post นี้ จะขอพูดคร่าวๆก่อน แล้วถ้าว่างๆจะมาเขียนอธิบายกันอีกทีว่า มันทำยังไงบ้าง? สำหรับตอนนี้ถ้าใครยังไม่รู้ และต้องการรู้ว่ามันคืออะไร ทำยังไง? เพื่อจะได้ลองทำเลย.. ก็ไปอ่านเอาเองก่อนที่ https://developers.google.com/products/ ไม่ใช่เรื่องยากอะไร..

เอาหล่ะ.. งั้นเราก็เริ่มต้นด้วยการไปใน Developer Console เพื่อ Create Project มา 1 ตัว จากนั้นก็ไปที่เมนู “Credential” เพื่อ Create Key ต่างๆมาใช้งานดังนี้!!

API Key

ค่านี้จะใช้สำหรับไว้ Authenticate App ของคุณเวลาเรียกใช้งาน ในบางงานที่คุณต้องการดึงค่า หรือดูข้อมูลทั่วๆไป ที่ไม่ได้เป็น private user data ก็ใช้แค่ตัว API Key นี่อย่างเดียวพอ .. แต่ถ้าข้อมูลหรืองานที่จะทำไปเกี่ยวข้องกับข้อมูลส่วนตัวของแต่ละคน เช่น Calendar,  หรือ Web Master Tools ตามที่ผมกำลังจะทำอยู่นี้ จำเป็นต้องใช้ Key 2 ตัว ตามด้าล่าง..

Client ID & Secret Key

2 ค่านี้เราต้องสร้างขึ้นมา เพื่อใช้สำหรับการทำ Authorized API access (OAuth 2.0) สำหรับการเอา Acess Token มาใช้งาน .. อย่างที่บอกไปตะกี้ว่า.. การจะเอาข้อมูลของ Web Master Tools มันเป็น private user data !! ดังนั้น.. จึงต้องมีการ OAuth 2.0 ให้ User Allow หรือยินยอมให้ App ของเราเข้าไปสืบค้น หรือแก้ไขปรับเปลี่ยนข้อมูลได้

********************************************************************
*** ค่า API Key, Client ID และ Secret Key นี้!! ควรเก็บไว้เป็นความลับนะ ใช้เอง ไม่ต้องไปแบ่งให้ใครรู้หล่ะ !!! ***
********************************************************************

Google API – Usage Limit เค้ากำหนดไว้ที่เท่าไหร่??

สำหรับ Web Mastertools (หรือชื่อใหม่คือ Search Console) แล้ว.. ทาง Google ระบุไว้ว่า “Google Webmaster Tools API has a default limit of 1,000,000 queries per day. ” ก็คือ ได้ 1,000,000 queries (คำสั่ง) ต่อหนึ่งวันนั่นแหละ สำหรับงานนี้ เราสบายๆ  ส่วนข้อจำกัดของตัวอื่นก็ไปดูเอาได้ที่ API ของแต่ละ Product นะ


 

เริ่มเขียนโปรแกรม!!!

( โปรดทราบ!!! ที่เขียนนี่เป็นแค่ตัวอย่างนะ .. อยากทำอะไรแบบไหน? ก็ไปปรับแต่งกันเอา!! )

สมมุติไฟล์ชื่อ fix_tag_error.php

require ไฟล์ที่ต้องใช้

อย่างที่บอกไปตอนต้น ผมถนัด PHP จึงไป Load Client libraries สำหรับเชื่อมต่อกับ Google APIs ที่เป็นภาษา PHP มาใช้ (https://developers.google.com/api-client-library/php/?hl=th) แล้วเรียกมาใช้งาน
พร้อมกับเรียกไฟล์ wp-load.php ของ WordPress มาด้วย เพื่อเตรียมใช้คำสั่งต่างๆของ WordPress ต่อไป ..
ส่วนไฟล์ lib.class.php อันนั้นเป็นไฟล์ที่ผมทำขึ้นมาเอง เพื่อใช้สำหรับเรียกใช้ หรือจัดเก็บค่า Option ต่างๆที่ Database (ในกรณีนี้ คือเก็บค่า Access Token ตัวล่าสุดของเรานั่นแหละ)

require_once ('/google-api-php-client-master/src/Google/autoload.php'); // or wherever autoload.php is located
require_once ('/libs/lib.class.php');
require_once ('/wp-load.php'); 

 

เรียกใช้ Class และ Config ค่าต่างๆ

ทำการเรียกใช้ Google Client โดยระบุ Key ต่างๆที่เราไป Create ไว้ตอนแรกเข้าไป…  ซึ่งด้วย libraries ตัวนี้ มันทำงานได้กับ Products ของ Google แทบจะทุกตัว ดังนั้นเวลาจะใช้งาน เราก็ต้องระบุบอกมันไปที่ setScopes ว่า เราจะใช้ Service ตัวไหน? จะแบบ Read Only หรือเข้าไปจัดการได้ด้วย? (ของ WebMaster Tools ดูได้ที่นี่.. https://developers.google.com/webmaster-tools/v3/prereqs) และอีกอย่าง.. ต้องระบุ setAccessType เป็น offline ด้วย! เพื่อบอกว่าเราจะใช้งาน แม้ไม่ได้ Login หรือ Online อยู่.. เพราะต่อไปเราจะเข้าใช้ระบบ โดยไม่ต้องมานั่งรอกด Allow กันอีก

$client = new Google_Client();
$client->setClientId("xxxxxxxxxxxxxxxxxxx");
$client->setClientSecret("xxxxxxxxxxxxxxxxxxx");
$client->setRedirectUri("http://www.yourURL.com/fix_tag_error.php");
$client->setScopes(Google_Service_Webmasters::WEBMASTERS);
$client->setAccessType("offline");

 

เตรียมการรับค่า Code หลังจากส่งไป OAuth 2.0 แล้วเอามา exchange ขอ AccessToken

ชุดนี้เป็นการเตรียมการไว้ เมื่อ Google redirect กลับมาหาเรา หลังจากการทำ OAuth แล้ว โดยพี่แกจะแปะ Parameter “code” ต่อท้ายมาด้วย .. เราก็เอามา Exchange เพื่อขอ AccessToken สำหรับใช้งาน และเก็บค่า AccessToken นี้ไว้เข้า Database เพื่อจะเอาไว้ใช้สำหรับ Refreh Token อีกครั้งในการทำงานครั้งต่อๆไป เมื่อตัวเดิมมันหมดอายุ

if (isset($_GET['code'])) {
  $client->authenticate($_GET['code']);
  if($access_token = $client->getAccessToken()) {
    $libs->update_option('google_webmaster_token', $access_token);
  }
}

ตัว Access Token ที่เราได้มา มันจะเป็น JSON ประมาณนี้..

{
"access_token":"xxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"token_type":"Bearer",
"expires_in":3600,
"refresh_token":"x/-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"created":1441171503
}

 

เอาค่า AccessToken มาเช็ค ถ้าหมดอายุก็ Resfresh ใหม่ ถ้าไม่มีก็ส่งไป OAuth ซะ!! จากนั้นดึงค่า Crawl Error มา ก่อนจะ Fixed มัน

ตอนนี้แบ่งเป็นส่วนๆลำบาก งั้นขอพูดยาวๆ แบบเป็นขั้นตอนทีเดียวเลยละกัน ว่าทำอะไรมั่ง? ไล่ดูตาม Code เอาละกันนะ!!

 

  • ไปหาค่า Access Token ใน Database ว่ามีรึมั้ย ???
    • ถ้าไม่มี – สั่งสร้าง URL สำหรับให้เราไป  OAuth และ Allow App ของเรา
    • ถ้ามี
      • Set Access Token เข้าตัว Google Client
      • แล้วเช็คดูว่า Access Token ตัวนี้หมดอายุหรือยัง?
      • ถ้าหมดอายุแล้ว!
        • decode Access Token ที่เป็น JSON ออกมา เพื่อจะเอาแค่ค่า “refresh_token” แล้วส่งไปขอ Access Token ตัวใหม่
        • Save Access Token ตัวใหม่เข้า Database เพื่อใช้ต่อไป
        • (ขั้นตอนนี้ มันจะ Set Access Token ตัวใหม่เข้าไปเอง เราไปทำงานอื่นต่อได้เลย)
      • เริ่มทำการค้นหา URL Crawl Error ด้วยการ New Service “Google_Service_Webmaster
      • ระบุว่าต้องการหาข้อมูล เว็บ” welovepro.com” ที่ category เป็น “notFound” (หรือ 404 นั่นแหละ) และ platform เป็น “web” (ถ้าเป็นของมือถือ ก็จะเป็น “smartphoneOnly” หรือ “mobile“) พวกค่าต่างๆ และ Method ที่เราจะเรียกใช้อะไรได้บ้าง? แบบไหน? ดูได้ที่นี่ .. https://developers.google.com/webmaster-tools/v3/ (เช่นเคย Product อื่นๆ ไปหาดูที่ Google เอานะ)
      • เมื่อได้ Return กลับมา ก็ลองมา foreach ดูว่ามี URL ที่ Error บ้างมั้ย?
        • ถ้าไม่มี – OK แจร่ม! จะเก็บ Log อะไรต่อก็แล้วแต่
        • ถ้ามี!
          • ลองหาดูซิ! ว่ามี URL ที่ขึ้นต้นด้วย tag/ รึเปล่า?  (เพราะตามที่บอก งานนี้เราต้องการแก้เพิ่ม Tag เข้าไป .. ถ้างง กลับไปอ่านข้างบน!)
            • ถ้าไม่มี – ไม่ต้องทำอะไร ลองดูไปเรื่อยๆ
            • ถ้ามี!
              • เอา URL มาตัดและ replace เพื่อหาคำที่เป็น Tag เพียวๆ
              • เอา Tag ไป Query Search ใน WordPress หา Post ที่เกี่ยวข้องกับ Tag นี้
              • ถ้าเจอ ว่ามี Post ที่ใกล้เคียงกัน .. ก็ while ดูแต่ละ Post แล้วเช็คดูดิว่า Post นั้นมี Tag ตัวนี้หรือยัง??
              • ถ้ามีแล้ว – ข้ามไป ไม่ต้องไปปรับอะไร
              • ถ้ายังไม่มี! 
                • จัดการเพิ่ม Tag เข้าไปด้วยคำสั่ง wp_set_object_term()
                • ถ้า Add เรียบร้อยก็ดีไป .. ถ้า Add แล้วไม่ผ่าน ก็เก็บ Log ไว้ดูหรือจะทำอะไรก็แล้วแต่
              • มาถึงตอนนี้ ได้จัดการ Add Tag ที่ต้องการเข้าไปแล้ว (หรืออาจจะมีอยู่แล้ว) นั่นแสดงว่า OK ละ!! เราสามารถบอก Google ได้แล้ว ว่าเราแก้แล้วนะ
              • ทำการแจ้ง markAsFixed ตัว URL ที่ Error ตัวนั้นไปบอก Google ว่าฉันจัดการแก้แล้วจ้า!!  (อย่าลืมใส่ category กับ platform ให้เหมือนตอนที่ไปหามาด้วย)
$webmasterToken = $libs->get_option('google_webmaster_token');

if($webmasterToken) {
       
        $client->setAccessToken($webmasterToken);
       
        if($client->isAccessTokenExpired()) {
            
            $google_token= json_decode($webmasterToken);
            $client->refreshToken($google_token->refresh_token);
            
            $access_token = $client->getAccessToken();
            $libs->update_option('google_webmaster_token', $access_token);
            
        } 

        /**  --- Start Find Error & Fix --- **/
        $service = new Google_Service_Webmasters($client);
        $urlcrawlerrorssamplesList = $service->urlcrawlerrorssamples->listUrlcrawlerrorssamples("http://www.welovepro.com/", "notFound", "web");

        foreach ($urlcrawlerrorssamplesList as $item) {
            if($item->pageUrl){
                if (preg_match("/^tag\//i", $item->pageUrl)) {
            
                    $tmparr = explode("/", $item->pageUrl);
                    $editingTag = str_replace("-", " ", urldecode($tmparr[1]));
            
                    $args = array(
                        'post_type' => 'post',
                        's' => $editingTag,
                        'posts_per_page' => 10,
                        'orderby' => 'date',
                        'order'   => 'ASC'
                    );
             
                    $query = new WP_Query( $args );

                    if ( $query->have_posts() ) {
                        while ( $query->have_posts() ) {
                            $query->the_post();
                    
                            if( !has_term( $editingTag, 'post_tag', $post->ID ) ){
                                $term_taxonomy_ids = wp_set_object_terms( $post->ID, $editingTag, 'post_tag', true );
                            } 
                        }  //while
                
                         // == fixed edit to Google
                        $urlcrawlerrorsMarkAsFixed = $service->urlcrawlerrorssamples->markAsFixed("http://www.welovepro.com/", $item->pageUrl, "notFound", "web");
                
                    } 
                    wp_reset_postdata();
               
                } 
            }  
        }

}else{ 
   $authUrl = $client->createAuthUrl();
   echo "<a class='login' href='" . $authUrl . "'>Connect Me!</a>";
}

** หมายเหตุ ** ตามตัวอย่างเป็นการดึง Error 404 ที่เจอบน Platform Web เท่านั้น!! ถ้าจะเปลี่ยนเป็น Error อื่นๆ หรือจะดู Platform ที่เป็น Mobile, SmartPhone ก็ปรับค่าการค้นหาเอาใหม่นะ

 

เก็บ Log การทำงาน + ตั้ง Crontab ให้มันจัดการให้เราทุกวัน [optional]

ขั้นตอนนี้เป็น Option เพื่อความสะดวก แล้วแต่ใครจะทำหรือไม่ทำ..

อย่างผมในโปรแรมที่ใช้ ผมก็จะมีตัวแปรเก็บ Log ขั้นตอนการทำงานต่างๆ ว่ามัน เจอ Error อะไรบ้าง? แล้ว Search เจอ Post มั้ย? เสร็จแล้ว Add Tag เรียบร้อยมั้ย? สั่ง Fixed OK รึเปล่า? พวกนี้ .. แล้วส่งเมล์มาแจ้งผลการทำงานให้ผมดู .. และผมก็ตั้ง Crontab ให้มันไป ค้นหา และแก้ไขทุกวัน จนกว่ามันจะหมดแหละ!!

 

สรุป!!

โปรแกรมในนี้ เป็นแค่ตัวอย่าง  idea และวิธีทำเบื้องต้น ในการเชื่อมต่อ เพื่อกระทำการใดๆกับ Product ของ Google ซึ่งมี API  ให้เชื่อมต่อหลาย Products เลยตอนนี้ !!!  ที่ยกตัวอย่างมาเป็นการทำกับ Google Web Master Tools หรือชื่อใหม่ที่เค้าตั้งมาคือ.. “Search Console” ส่วนใครปรับไปทำอะไรกับงานของตัวเอง ก็คงต้องไปดู Document ส่วน Developer ของ Google เพิ่มเติมเอาอีกทีนะ

วันนี้ขอลาแค่นี่แหละ!! เมื่อยนิ้วแล้ว….