我们进入淘宝网,在首页查看源代码
可以看到全是js,并没有直观的页面元素,因为首页的内容都是动态生成的,这时候我们就需要对网页的链接做一些分析了。
现在我想爬取淘宝网上所有关于Ipad的信息,那么现在首页的搜索框输入‘Ipad’
查看链接得到
https://s.taobao.com/search?q=ipad&imgfile=&js=1&stats_click=search_radio_all%3A1&initiative_id=staobaoz_20180609&ie=utf8&bcoffset=3&ntoffset=3&p4ppushleft=1%2C48&s=44
拿到这个链接后,对这一堆值我也是一脸茫然,不过第一个q应该是搜索的条目,然后我对后面的值逐个修改发现只有q和s是对对搜索内容有明显影响的,s代表当前的个数,比如s为1到44代表的是第一页,45到88是第二页。分析完成后后面的工作就好办了
第一步:设定需要取到哪些 内容
class GoodsItem(scrapy.Item):
title = scrapy.Field()
price = scrapy.Field()
shop = scrapy.Field()
deal = scrapy.Field()
第二步:拿到初始的url
# 经过测试证明参数只需要传q和s的内容就可以进入相应的页面,所以这里只需要拿到q和s的值
def start_requests(self):
base_url = 'https://s.taobao.com/search?'
params = {}
for keyword in ['ipad', 'iphone', '小米手机']:
params['q'] = keyword
for page in range(10):
params['s'] = page * 44
full_url = base_url + urlencode(params)
yield scrapy.Request(url=full_url, callback=self.parse,dont_filter=True)
第三步:解析页面
拿到存放商品内容的部分
def parse(self, response):
goods_list = response.xpath('//*[@id="mainsrp-itemlist"]/div/div/div[1]')
for goods in goods_list:
item = GoodsItem()
item['price'] = goods.xpath('div[5]/div[2]/div[1]/div[1]/strong/text()').extract_first()
item['deal'] = goods.xpath('div[5]/div[2]/div[1]/div[2]/text()').extract_first()
segments = goods.xpath('div[6]/div[2]/div[2]/a/text()').extract()
title = StringIO() # 可变字符串,做拼接时是在同一个对象上进行修改,不会创建新的对象,但是拿到的值不是字符串,通过getvalue()拿到里面的字符串
for segment in segments:
title.write(re.sub('\s', '', segment))
item['title'] = title.getvalue()
yield item
第四步:编写中间件
class TaobaoDownloadMiddleware(object):
def __init__(self, timeout=None):
self.timeout = timeout
# options = webdriver.ChromeOptions()
# options.add_argument('--proxy-server=http://uid:pwd@xxxxxx:xx') # 为selenium设置代理 uid:用户名 pwd:密码
self.browser = webdriver.Chrome(options )
self.browser.set_window_size(1000, 600)
self.browser.set_page_load_timeout(self.timeout)
def __del__(self):
self.browser.close()
def process_request(self, request, spider):
try:
self.browser.get(request.url)
return HtmlResponse(url=request.url, body=self.browser.page_source,
request=request, encoding='utf-8', status=200)
except TimeoutException:
return HtmlResponse(url=request.url, status=500, request=request)
def process_response(self, request, response, spider):
return response
def process_exception(self, request, exception, spider):
pass
# 依赖注入--crawler--通过该对象可以对整个项目进行操作
@classmethod
def from_crawler(cls, crawler):
return cls(timeout=10)