好长一段时间没怎么碰爬虫,我估计得熟悉一下,要不然上手就遇到问题,直接拿大厂图片来试试,翻车分分钟?
目标是:
1.常规手段,request
2.框架 scrapy
网页分析:
这里我以风景图为关键词,输入后获得地址为‘https://image.baidu.com/search/index?tn=baiduimage&ct=201326592&lm=-1&cl=2&ie=gb18030&word=%B7%E7%BE%B0%CD%BC%C6%AC&fr=ala&ala=1&alatpl=adress&pos=0&hs=2&xthttps=111111’,这里%B7%E7%BE%B0%CD%BC%C6%AC就是‘风景图’的url编码后的字符,打开检查工具,随便找一个下级页面的url,发现响应里面居然不是html,而是一大堆js,可是我没学过js,而且翻了翻,5w行,不翻车不舒服斯基?遂放弃,准备曲线救国。
注意到这里是瀑布流式的图片翻页,因此查看查看ajax,图片往下拖,出来新的内容:
这里status code是200,最爱这个了,直接把url复制到地址栏!出来一大堆:
感觉好像就是我们要的数据啊~开整
Requests
首先是requests方法,先对上面得到的url进行删减参数,一个个试,最后得到“http://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&word=%E9%A3%8E%E6%99%AF%E5%9B%BE&pn=30&rn=300”,现在是删哪个都不行了,其中pn应该是page number, 为了验证,继续下拉,发现下一个ajax请求里面的pn是60,确实就是翻页参数,那么rn是什么呢,我试试将其改成3000, 结果出来的结果多了许多,应该就是控制每页请求多少组数据,可以大一些,从而减少请求次数,要知道百度可是会屏蔽ip的啊~~。
页面中是json字符串,因此需要转化一下,另外爬取后期发现,这里只有缩略图url(小图url),而大图url是留空的,这里爬不到,也拿不到大图的页面地址。罗马不是一天建成的,先拿小图,再找大图!
以下为源码:
import requests
import time
import random
import traceback
import json
import re
def get_url_list(temp, dp):
# 根据第一级url的规则,生成url列表
return [temp.format(i * 30) for i in range(dp)]
def get_text(url):
# 获取页面html信息参数
global headers
headers = dict()
headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36'
headers['Referer'] = 'http://image.baidu.com/search/index?tn=baiduimage&word=%E9%A3%8E%E6%99%AF%E5%9B%BE'
try:
response = requests.get(url, headers=headers)
response.encoding = 'utf-8'
except BaseException:
traceback.print_exc()
response = ''
return response.text
def get_img_url(url):
# 分析json数据,获取爬取到的url
time.sleep(2 + random.random())
response = get_text(url)
img_urls = []
if response is not None:
s = json.loads(response)
for i in s['data']:
try:
img_url = i['middleURL']
img_urls.append(img_url)
except (ValueError, KeyError) as v:
# print(v)
img_url = ''
continue