With nothing better to do, I put together an image scraper.
After scraping the images from a certain website, save them to a specified local directory, and at the same time generate the SQL statements that write them into the database.
The approach is as follows:
- Get the URLs of the images on the page
- Download them locally based on the image URLs
- Store the downloaded images in the specified directory, and generate the SQL that writes them into the database
The complete code is as follows:
<?php
class RetileImg
{
protected $url; // request URL
protected $url_status = false; // false means an http request, true means an https request
protected $img_path; // image storage path
protected $sql_path; // path where the SQL statement is saved
protected $domain_name; // domain name; if some images use relative paths, the domain name needs to be filled in
public function __construct($url, $url_status, $img_path, $sql_path, $domain_name)
{
$this->url = $url;
$this->url_status = $url_status;
$this->img_path = $img_path . "/" . date("Ymd") . "/";
$this->sql_path = $sql_path . "/";
$this->domain_name = $domain_name;
}
/**Fetch the page
* @return bool|string
*/
public function curl_web()
{
$url = $this->url;
$url_status = $this->url_status;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 100);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 100);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $url_status);
$ch_content = curl_exec($ch);
return $ch_content;
}
/**Match the image paths on the page
* @param $content
* @return mixed|null
*/
public function get_img_from_html($content)
{
$pattern = "/<img.*?src=[\'|\"](.*?)[\'|\"].*?[\/]?>/";
$html_data = htmlspecialchars_decode($content);
preg_match_all($pattern, $html_data, $match);
if (!empty($match[1])) {
return $match[1];
}
return null;
}
/**Get all image paths on the page
* @return mixed|null
*/
public function get_img_urls()
{
$url = $this->url;
$html_data = $this->curl_web($url);
$img_urls = $this->get_img_from_html($html_data) ?? null;
$domain_name = $this->domain_name;
$urls = [];
foreach ($img_urls as $k => $v) {
if (empty($v)) {
unset($k[$v]);
}
$http_top = mb_substr($v, 0, 4);
if ($http_top != 'http' && !empty($domain_name)) {
$v = $domain_name . $v;
};
$urls[] = $v;
}
return $urls;
}
/**Download the images to local storage
* @throws Exception
*/
public function download()
{
$img_urls = $this->get_img_urls();
$img_path = $this->img_path;
$sql_path = $this->sql_path;
$mimes = array(
'bmp',
'gif',
'jpg',
'png',
);
$sql = "insert into img_data ('img_name','img_url','img_description','add_time') value (";
foreach ($img_urls as $k => $v) {
$ext = mb_substr($v, -3);
// if it matches the type we want
if (in_array($ext, $mimes)) {
$number = random_int(10, 99999);
$img_name = date("YmdHis") . $number;
$content = file_get_contents($v);
if (!is_dir($img_path)) {
mkdir($img_path, 0777, true);
}
//echo "图片下载" . $content . PHP_EOL;
$file_name = md5($img_name);
$file_path = $img_path . $file_name . "." . $ext;
file_put_contents($file_path, $content);
$sql .= "'" . $file_name . "',";
$sql .= "'" . $file_path . "',";
$sql .= "'" . $file_name . "',";
$sql .= date("Y-m-d H:i:s");
}
}
$sql .= ");";
if (!is_dir($sql_path)) {
mkdir($sql_path, 0777, true);
}
file_put_contents($sql_path . "sql.txt", $sql);
}
}
// execute the image fetch
header("Content-type: text/html; charset=utf-8");
$img_data = new RetileImg(
"https://erik.xyz/2014/10/17/zhe-shi-yi-ge-kai-shi-de-jie-shu/",
true,
"./img",
"./sql",
"https://erik.xyz"
);
$img_data->download();

