我们有时需要爬取的数据并不在同一页上,不能简单的请求一个url然后解析网页。以dytt网站为例,例如我们想要“国内电影”里所有电影的名字,和点进去它的图片(在另一个网页中)。如何把这两个数据定义为同一个item对象呢?
一、创建scrapy项目
在PyCharm终端依次输入:
注:genspider后面的网址不需要带http://和url最后的斜线,.html的网页末尾一定不要有‘/’ 最后测试一下这个url有没有robots协议或者反爬手段等.
二、items.py中定义数据的结构
我们需要的一个是电影的名字,一个是电影图片url
class DyttMovieItem(scrapy.Item): name = scrapy.Field() src = scrapy.Field()
三、定位、爬取数据
分析网页源代码,如下标签中包含着我们需要的电影名字,以及其图片所在的另一个网页的url。我们需要获取这两个信息
用xpath解析找到我们需要的信息,注意图片所在的url需要拼接
def parse(self, response): a_list = response.xpath('//div[@class="co_content8"]//td[2]//a[2]')
for a in a_list: name = a.xpath('./text()').extract_first() url = '自己输入域名' + a.xpath('./@href').extract_first()
四、对第二页的链接发起访问
我们以及获取到url,接下来就要访问这个图片的url,从而才能提取出图片的地址。
def parse(self, response): a_list = response.xpath('//div[@class="co_content8"]//td[2]//a[2]')
for a in a_list: name = a.xpath('./text()').extract_first() url = '自己输入域名' + a.xpath('./@href').extract_first()
yield scrapy.Request(url=url, callback=self.parse_second)
def parse_second(self, response): print('999999999999')
之后是对图片地址的解析(具体过程略)
def parse_second(self, response): src = response.xpath('//div[@id="Zoom"]//img/@src').extract_first() print(src)
但还有一个问题,我们需要将图片的src和电影的名字对应好,一并获取,这时就需要meta参数。
def parse(self, response): a_list = response.xpath('//div[@class="co_content8"]//td[2]//a[2]')
for a in a_list: name = a.xpath('./text()').extract_first() url = '自己输入域名' + a.xpath('./@href').extract_first()
yield scrapy.Request(url=url, callback=self.parse_second, meta={'name': name})
def parse_second(self, response): src = response.xpath('//div[@id="Zoom"]//img/@src').extract_first() name = response.meta['name']
movie = DyttMovieItem(name=name, src=src) yield movie
五、保存数据到管道
先开启管道,再在管道中下载数据
class DyttMoviePipeline:
def open_spider(self, spider): self.f = open('movie.json', 'w', encoding='utf-8')
def process_item(self, item, spider): self.f.write(str(item)) return item
def close_spider(self, spider): self.f.close()
六、所有代码
movie.py
import scrapy from dytt_movie.items import DyttMovieItem
class MovieSpider(scrapy.Spider): name = 'movie' allowed_domains = ['自己输入域名'] start_urls = ['国内电影的url']
def parse(self, response): a_list = response.xpath('//div[@class="co_content8"]//td[2]//a[2]')
for a in a_list: name = a.xpath('./text()').extract_first() url = '自己输入域名' + a.xpath('./@href').extract_first()
yield scrapy.Request(url=url, callback=self.parse_second, meta={'name': name})
def parse_second(self, response): src = response.xpath('//div[@id="Zoom"]//img/@src').extract_first() name = response.meta['name']
movie = DyttMovieItem(name=name, src=src) yield movie
items.py
import scrapy
class DyttMovieItem(scrapy.Item): # define the fields for your item here like: name = scrapy.Field() src = scrapy.Field()
pipelines.py
class DyttMoviePipeline:
def open_spider(self, spider): self.f = open('movie.json', 'w', encoding='utf-8')
def process_item(self, item, spider): self.f.write(str(item)) return item
def close_spider(self, spider): self.f.close()
总结
最关键的是上面的四,其他步骤都是套路。
神龙|纯净稳定代理IP免费测试>>>>>>>>天启|企业级代理IP免费测试>>>>>>>>IPIPGO|全球住宅代理IP免费测试