做了接近一个月爬虫,中间爬到数据多的爬过唯品会,dpchallenge,frilly。百度图片和1688也是取了一部分数据来。这里做一些爬虫技术总结记录,包括基本的requests使用,json,bs4,OrderedDict,下载图片,多进程以及post一个数组。
首先,基本的爬虫以唯品会(这里以女装做示范),主要用以接口获取json数据,json解析,json格式化。
首先获取一下他的分类列表,由于返回的是callback里的函数,便去掉前后一些字符然后json格式化。
req=requests.Session() cateurl='https://category.vip.com/ajax/getCategory.php?callback=getCategory&tree_id=117' pplist=req.get(cateurl).text ppjson=json.loads(pplist[12:-1]) pparr=ppjson['data'][0]['children'][0]['children']
之后访问分类的具体页面,用一点正则到他的js里解析出productIds,解析json,然后再通过里面的每个productid的拼接构成一个url,获取到商品服装信息(这里可得缩略图)。再进入服装详情页,得到商品大图。
for item in pparr:
searchurl='https://category.vip.com/'+item['url']
sec1=req.get(searchurl
jsonpic=re.findall(r'"productIds":(.*?),"',sec1.text)
piclist=json.loads(jsonpic[0])
for n in range(2):
productIds='%2C'.join(map(str,piclist[50*n:(n+1)*50]))
resp=req.get('https://category.vip.com/ajax/mapi.php?service=product_info&productIds='+productIds+'&warehouse=VIP_SH')
projson=json.loads(resp.text)
if cate > -5:
for j in projson['data']['products']:
detail=req.get('https://detail.vip.com/detail-'+str(j['brandId'])+'-'+str(j['productId'])+'.html?f=ad')
match=re.findall(r'<a href="(.*?)" class="J-mer-bigImgZoom">',detail.text)
for url in match:
print(url)
插一个从网页下载图片到本地的小技巧
img=req.get(imageurl).content
with open('test.jpg','wb') as f:
f.write(img)
f.close()
dpchallenge.com,这是个摄影网站,除了爬图片还得爬摄影信息及评论,主要靠beautifulsoup和正则解析html文本。
这里先爬了信息,其中也包括图片地址。之后在把所有图下载下来。
这里做一部分beautifulsoup的记录
soup=BeautifulSoup(response.text,"lxml")
source_url=soup.find_all('标签',{'属性':'值(写True则代表有这个属性)'
另一个这里要注意的便是OrderedDict,由于python的object读取显示出来时会乱序或者并不是按写入的顺序显示的。所以需要用OrderedDict作代替
from collections import OrderedDict test=OrderedDict() test["c"]="1" test["b"]="2" test["a"]="3" print(test)
最后这里在做一下爬虫期间所用的多进程的简单使用,这里用到了进程池以及进程锁:
from multiprocessing import Pool,Manager
def func(n,lock):
with lock:
print(n)
if __name__=="__main__":
pool=Pool()
lock=Manager().Lock()
for i in range(10):
pool.apply_async(func, (i,lock))#这边也可以加回调
pool.close()
pool.join()
最后考虑一个post时发现的问题,也是平常可能会忽略而出错的。
http://test.ganjiacheng.cn/testspider/test.php是一个返回post数据的接口
在js的jquery的ajax里,
$.post("./test.php",{du:"0",data:["1","2","3"]},function(data){
console.log(data)
})
//结果:{"du":"0","data":["1","2","3"]}
而在python里
import requests
import json
post_data={
"du":"0",
"data":["1","2","3"],
}
res=requests.post('http://test.ganjiacheng.cn/testspider/test.php',data=post_data)
print(res.json())
#结果:{'du': '0', 'data': '3'}
也便是数组形式如[]在post传输过程是不能保持的,上面的post_data传输的信息形式应该如du=0&data%5B%5D=1&data%5B%5D=2&data%5B%5D=3。
后来用了拼接的方法来解决这个问题。
有待提升的地方,在有较多js操作及判断的网页中,要爬到对应信息需进行复刻同样的js操作,首先要读懂js,再来要自己实现一遍,对于综合能力要求还是比较高的。对于1688这种检测到爬虫的一些行为后会需要你登录后进行操作,虽然登录后通过chrome拿到cookie是可以使用的,但可能会有时限等限制。还有待探索!
赞赏一下
支付宝打赏
微信打赏