刚学的爬虫,之前都是学的爬取静态网页图片,这次尝试爬取百度的图片,用xpath解析网页获取的都是空列表,后来查阅资料才知道百度图片的网页是动态的,采用的都是Ajax+JSON机制。
网页原始数据是没有图片的,通过运行JavaScript,把图片数据插入到网页的HTML标签中。所以我们在开发者工具中虽然能看到这个HTML标签,但是网页的原始数据其实没有这个标签,它只在运行时加载和渲染。真实的图片信息被打包放在JSON文件当中,所以真正要解析的是JSON文件。
百度搜索柯南
点击Network–XHR,在往下滑动滚动条时,会连续出现名为acjson的请求,再点击Preview,我们看到这是一条JSON数据,点开data,我们看到这里面有30条数据,每一条都对应着一张图片。
图片的url地址就在data里面的middleURL中,点击data,然后随便点一条数据,比如0,然后往下面拉,会看到如下图所示结果
但是我们要获取的图片的url地址在json数据里,json文件的url在Headers下的Request URL中,并且我们会发现所有的json文件的url只有pn字段保持以30为步长递增,其余不变
编写我们的spider,因为一个json数据只有30张图片,所以我们要重写start_urls,下图代码的url就是上图中的Request URL,需要将其pn改变,所以用for循环
import scrapy
from meizi
.items
import MeiziItem
import json
class MeiziSpiderSpider(scrapy
.Spider
):
name
= 'meizi_spider'
allowed_domains
= ['image.baidu.com']
def start_requests(self
):
for i
in range(30,120,30):
url
="https://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&ct=201326592&is=&fp=result&queryWord=柯南&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=-1&z=&ic=&hd=&latest=©right=&word=柯南&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=1&fr=&expermode=&force=&pn={}&rn=30".format(i
)
yield scrapy
.Request
(url
, callback
=self
.parse
)
def parse(self
, response
):
imgs
=json
.loads
(response
.body
).get
("data")
for img
in imgs
:
item
=MeiziItem
()
item
['image_urls']=[img
['middleURL']]
print(img
['middleURL'])
yield(item
)
items文件
import scrapy
class MeiziItem(scrapy
.Item
):
image_urls
=scrapy
.Field
()
settings文件,!!!注意这里为了防止防盗链,在DEFAULT_REQUEST_HEADERS里面一定要添加referer属性,否则下载下来的图片会显示图片失败!!!
BOT_NAME
= 'meizi'
SPIDER_MODULES
= ['meizi.spiders']
NEWSPIDER_MODULE
= 'meizi.spiders'
ROBOTSTXT_OBEY
= False
DEFAULT_REQUEST_HEADERS
= {
"referer":"http://image.baidu.com/search/",
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en',
'User-agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36'
}
ITEM_PIPELINES
= {
'scrapy.pipelines.images.ImagesPipeline':1
}
IMAGES_STORE
= "E:/meizi/"
pipelines文件,因为这里使用了scrapy自带的下载图片功能,所以pipelines文件就不用修改了,只需要在settings文件中将 ‘meizi.pipelines.MeiziPipeline’: 300这句注释掉,添加一句’scrapy.pipelines.images.ImagesPipeline’:1
class MeiziPipeline:
def process_item(self
, item
, spider
):
return item
最后执行下start文件
from scrapy
import cmdline
cmdline
.execute
("scrapy crawl meizi_spider".split
())
爬取结果
转载请注明原文地址:https://ipadbbs.8miu.com/read-4935.html