下面来玩点有难度的,试了一堆B2C,发现某宁还真是与众不同。用之前的方法:
import urllib
url = 'http://product.suning.com/102365475.html'
print urllib.urlopen(url).read()
会发现这次不顶用了,会提示错误信息:
HTTPError: HTTP Error 302: The HTTP server returned a redirect error that would lead to an infinite loop.
这回可不像之前那么容易,想要搞定这个问题,需要有一点点的HTTP知识。再次打开httpfox, 在运行之前把cookie清空,以免然并卵。运行httpfox, 显示完价格就可以停了。博主对HTTP也不熟,所以跟踪信息就一条一条看吧。可以通过查看content知道捕获到的内容。经过简单的分析可以知道res.xxx的网址都是获取样式表,js脚本等资源的,imgxxx是获取网页里的图片与图标的,这些不是我们关注的。慢慢找会发现这么一条内容:
showSaleStatus({"cacheMinute":600,"saleInfo":[{"accountPlace":"","deptNo":"0001","factorySendFlag":"0","govPrice":"","invStatus":"1","juId":"","manageInvFlag":"0","netPrice":"15999.00","ownerPlace":"D017","partNumber":"000000000102365475","priceType":"0","promotionPrice":"15999.00","refPrice":"20624.00","salesOrg":"1900","sendAvalidTime":1436367973160,"sendCityId":"9254","vendor":"0010016172","vendorCode":"","vendorType":""}]});
promotionPrice和网页看到的价格一致,就是你了。提示一下虽然这里看到netPrice和promotionPrice价格一致,为什么博主认定是promotionPrice呢?原因在于多对比,就会发现实际的价格是促销价了。另外有一点,现在网站都喜欢用结构化的数据,因此type是json, xml, javascript的部分可以多留心。有时候可能content里会出现Error loading content (NS_ERROR_DOCUMENT_NOT_CACHED)的报错信息,这个时候把网址复制出来浏览器上一打,看看里面的真正内容是什么即可。
以上信息来至url:http://www.suning.com/webapp/wcs/stores/ItemPrice/000000000125695848__xxxx_xxxxx_1.html 试了一下其实这个网址是可以直接访问的,但是为了灵活起见,还是往前追一下这三串数字怎么来的。慢慢分析会发现,000000000125695848真正的名称叫curPartNumber,只要一开始的网页可以正常的request就可以找到,剩下两串数字是定位用的,你在哪个城市,哪个区,这些信息是通过http://ipservice.suning.com/ipQuery.do进行查询的。
经过这样逆向的分析就可以想办法得到完整的网址了,这一次的访问需要模拟浏览器的行为,需要有header, cookie等内容和网站进行交互,不然又要被重定向了。具体参见示例:
import urllib2
import cookielib
import re
def get_part_number(url):
#httpHandler = urllib2.HTTPHandler()
cookie = cookielib.CookieJar();
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie));
response = opener.open(url)
m = re.search(r'<input type="hidden" id="curPartNumber" value="(\d+)"/>', response.read())
return m.group(1)
def get_price_url(part_number):
location = urllib2.urlopen('http://ipservice.suning.com/ipQuery.do').read()
loc_code_dict = eval(location)
price_url = 'http://www.suning.com/webapp/wcs/stores/ItemPrice/%s__%s_%s_%s.html' %(part_number, loc_code_dict['cityCommerceId'], loc_code_dict['districtCommerceId'], loc_code_dict['districtLESId'].strip('0'))
return price_url
def sn_parse(url):
price_url = get_price_url(get_part_number(url))
#httpHandler = urllib2.HTTPHandler()
cookie = cookielib.CookieJar();
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie));
response = opener.open(price_url)
m = re.search(r'"saleInfo":\[(.+)\]', response.read())
price_dict = eval(m.group(1))
price = price_dict['promotionPrice']
return price
if __name__ == '__main__':
url = 'http://product.suning.com/102365475.html'
print 'SN 5D: %s' %sn_parse(url)