今日头条街拍图片抓取

爬取目标:

    今日头条右上角输入:街拍


之后得到的是这样一个磨人的小妖精


分析网页之后发现是Ajax技术(我用的是Chrom的开发者工具,点XHR之后发现了常规的Ajax请求)

然后在细致的分析Preview里面的代码。会发现image_list里面包含了图片的链接,title里面包含了名称。这就是我们需要爬取的部分了如图


然后回到Headers,我们根据Request URL来构造GET请求。如下图


其中唯一的变化参数是offset,将其作为参数。来构造单个的Ajax请求。。代码如下:

def get_page(offset):
params = {
'offset': offset,
'format': 'json',
'keyword': '街拍',
'autoload': 'true',
'count': '20',
'cur_tab': '1',
'from': 'search_tab',
}
url = 'https://www.toutiao.com/search_content/?' + urlencode(params)
try:
response = requests.get(url)
if response.status_code == 200:
return response.json()
except requests.ConnectError:

return None

然后提取每一张图片的链接和名字,代码如下:

def get_images(json):
data = json.get('data')
if data:
for item in data:
title = item.get('title')
image_list = item.get('image_list')
if image_list:
for image in image_list:
yield {
'image': image.get('url'),
'title': title
}

在接下来就是保存了。崔大佬用的是名字来当做新建文件夹的名称,每一张图片的名字是其内容的MD5值,这样可以去除重复,代码如下:

def save_image(item):
if not os.path.exists(item.get('title')):
os.mkdir(item.get('title'))
try:
local_image_url = item.get('image')
new_image_url = local_image_url.replace('list','large')
response = requests.get('http:'+ new_image_url)
if response.status_code == 200:
file_path = '{0}/{1}.{2}'.format(item.get('title'), md5(response.content).hexdigest(), 'jpg')
if not os.path.exists(file_path):
with open(file_path, 'wb') as f:#
f.write(response.content)
else:
print('Already Downloaded', file_path)
except requests.ConnectionError:

print('Failed to Save Image')

最后运行结果如下:



    我感觉崔大佬代码很简练,学习他的还是需要一些python 的基础知识。重点应该学习一下他的编程思想。

不过觉得这个程序应该是用多进程下的图片,书上的原话是多线程。。。(采用与廖雪峰的对比)

也不知道是不是。不过大佬的书值得学习。也正在学习。目前市面上爬虫最好的一本了。附上最终完整代码:

import os
import requests
from urllib.parse import urlencode
from hashlib import md5
from multiprocessing.pool import Pool


GROUP_START = 0
GROUP_END = 2




def get_page(offset):
params = {
'offset': offset,
'format': 'json',
'keyword': '街拍',
'autoload': 'true',
'count': '20',
'cur_tab': '1',
'from': 'search_tab',
}
url = 'https://www.toutiao.com/search_content/?' + urlencode(params)
try:
response = requests.get(url)
if response.status_code == 200:
return response.json()
except requests.ConnectError:
return None



def get_images(json):
data = json.get('data')
if data:
for item in data:
title = item.get('title')
image_list = item.get('image_list')
if image_list:
for image in image_list:
yield {
'image': image.get('url'),
'title': title
}





def save_image(item):
if not os.path.exists(item.get('title')):
os.mkdir(item.get('title'))
try:
local_image_url = item.get('image')
new_image_url = local_image_url.replace('list','large')
response = requests.get('http:'+ new_image_url)
if response.status_code == 200:
file_path = '{0}/{1}.{2}'.format(item.get('title'), md5(response.content).hexdigest(), 'jpg')
if not os.path.exists(file_path):
with open(file_path, 'wb') as f:#
f.write(response.content)
else:
print('Already Downloaded', file_path)
except requests.ConnectionError:
print('Failed to Save Image')

def main(offset):
json = get_page(offset)
for item in get_images(json):
print(item)
save_image(item)#




if __name__ == '__main__':
pool = Pool()
groups = ([x*20 for x in range(GROUP_START, GROUP_END+1)])
pool.map(main, groups)
pool.close()
pool.join()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值