Baidu.php 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: Jaeger <JaegerCode@gmail.com>
  5. * Date: 2017/10/1
  6. * Baidu searcher
  7. */
  8. namespace QL\Ext;
  9. use QL\Contracts\PluginContract;
  10. use QL\QueryList;
  11. class Baidu implements PluginContract
  12. {
  13. private $is_pc = true;
  14. protected $ql;
  15. protected $keyword;
  16. protected $pageNumber = 10;
  17. protected $httpOpt = [
  18. 'headers' => [
  19. 'User-Agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36',
  20. 'Accept-Encoding' => 'gzip, deflate, br',
  21. ]
  22. ];
  23. const API = [
  24. 'PC' => 'https://www.baidu.com/s',
  25. 'M' => 'https://www.baidu.com/s',
  26. ];
  27. const RULES = [
  28. 'title' => ['h3', 'text'],
  29. 'link' => ['h3>a', 'href']
  30. ];
  31. const RANGE = '.result';
  32. /**
  33. * @var string
  34. */
  35. private $api;
  36. public function __construct(QueryList $ql, $pageNumber, $api)
  37. {
  38. $this->ql = $ql->rules(self::RULES)->range(self::RANGE);
  39. $this->pageNumber = $pageNumber;
  40. $this->api = self::API[$api];
  41. $this->is_pc = $api == "PC";
  42. }
  43. public static function install(QueryList $queryList, ...$opt)
  44. {
  45. $name = $opt[0] ?? 'baidu';
  46. $queryList->bind($name, function ($pageNumber = 10, $api = 'PC') {
  47. return new Baidu($this, $pageNumber, $api);
  48. });
  49. }
  50. public function setHttpOpt(array $httpOpt = [])
  51. {
  52. $this->httpOpt = $httpOpt;
  53. return $this;
  54. }
  55. public function search($keyword)
  56. {
  57. $this->keyword = $keyword;
  58. return $this;
  59. }
  60. public function page($page = 1, $realURL = false)
  61. {
  62. return $this->query($page)->query()->getData(function ($item) use ($realURL) {
  63. $realURL && $item['link'] = $this->getRealURL($item['link']);
  64. return $item;
  65. });
  66. }
  67. public function getCount()
  68. {
  69. $count = 0;
  70. $text = $this->query(1)->find('.nums')->text();
  71. if (preg_match('/[\d,]+/', $text, $arr)) {
  72. $count = str_replace(',', '', $arr[0]);
  73. }
  74. return (int)$count;
  75. }
  76. public function getCountPage()
  77. {
  78. $count = $this->getCount();
  79. $countPage = ceil($count / $this->pageNumber);
  80. return $countPage;
  81. }
  82. protected function query($page = 1)
  83. {
  84. $this->ql->get($this->api, [
  85. 'wd' => $this->keyword,
  86. 'rn' => $this->pageNumber,
  87. 'pn' => $this->pageNumber * ($page - 1)
  88. ], $this->httpOpt);
  89. return $this->ql;
  90. }
  91. /**
  92. * 得到百度跳转的真正地址
  93. * @param $url
  94. * @return mixed
  95. */
  96. protected function getRealURL($url)
  97. {
  98. if (empty($url)) return $url;
  99. $header = get_headers($url, 1);
  100. if (strpos($header[0], '301') || strpos($header[0], '302')) {
  101. if (is_array($header['Location'])) {
  102. //return $header['Location'][count($header['Location'])-1];
  103. return $header['Location'][0];
  104. } else {
  105. return $header['Location'];
  106. }
  107. } else {
  108. return $url;
  109. }
  110. }
  111. }