亲宝软件园·资讯

展开

爬虫连载系列(3)--爬取京东商城

飞小飞 人气:0
## 前言 这两天原本想在淘宝上爬点东西进行分析的,但没想到淘宝的反爬机制对我这个爬虫菜鸡充满了恶意。先是被数据的格式搞得焦头烂额,好不容易写好了测试一页的代码,准备美滋滋开始大显身手,爬取多页时,发现竟然被封IP了!呜呜┭┮﹏┭┮。于是,开始研究各种反反爬的机制,IP代理,多线程、模拟登陆... ...发现自己的盲区越来越大。眼瞅着与自己的博客更新计划越行越远,只好先换个目标,对某东下手。但并不代表我会放过它,等自己在修炼一段时间,再来会会它。下面,我们开始进入正题吧。 这次想做一个关于**糖果**的分析,于是爬取了京东共2700左右条的数据,这个数据应该是够自己分析了。京东比较坑的一点是,他的每一页是先加载一部分,另一部分是通过动态加载的。为此,我的解决办法是,使用Selenium构建模拟浏览器,先通过执行脚本,下滑到底部,等全部数据加载完成后,在进行读取。哦,对了,这次使用的解析库是xpath。 ### 要点 用到的库:selenium、urllib、pandas、csv、lxml 工具: python 3.7、jupyter notebook ## 分析 ### 网页分析 首先,我们进入京东商城,搜索框中输入**糖果**,进入开发者模式。 ![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ySX78DDF-1584365178843)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20200316202344764.png)\]](https://img-blog.csdnimg.cn/2020031621271260.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L01pcmFjbGVfSDEy,size_16,color_FFFFFF,t_70) 发现这也太简单了叭,按捺不住内心的鸡冻,马上就想要开始写代码。 慢着 ![img](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9kc3MwLmJkc3RhdGljLmNvbS83MGNGdUhTaF9RMVlueEdrcG9XSzFIRjZoaHkvaXQvdT0xNTc3MzE2MDc0LDI4MTE0ODk5ODQmZm09MTUmZ3A9MC5qcGc?x-oss-process=image/format,png) 我们先看看Network的输出, ![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nZSpnium-1584365178851)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20200316203358532.png)\]](https://img-blog.csdnimg.cn/20200316212747105.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L01pcmFjbGVfSDEy,size_16,color_FFFFFF,t_70) 细细看一下Preview中的商品,如果你点一下,你会发现只有30个商品,而页面中共有60个商品,你会发现事情并不简单。 下滑到底部后,你在刷新下Network输出,你会发现,这里多了个这个js文件 ![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OIU06gjc-1584365178852)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20200316203704329.png)\]](https://img-blog.csdnimg.cn/2020031621301732.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L01pcmFjbGVfSDEy,size_16,color_FFFFFF,t_70) 而这里就是剩下的30条数据。 哦,我懂了,不就是先加载30条数据,后30条数据在你滑动浏览的过程中加载嘛。 ![img](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9kc3MxLmJkc3RhdGljLmNvbS83MGNGdVhTaF9RMVlueEdrcG9XSzFIRjZoaHkvaXQvdT0zNjMwNDA3Nzc3LDMwNTQ0MjY2NzAmZm09MjYmZ3A9MC5qcGc?x-oss-process=image/format,png) 这时候,我们前面介绍的主角就登场了:Selenium 。通过它,构建一个虚拟浏览器,先执行一个脚本,下滑到最底部,加载完数据后我们在进行爬取。 **注意:**使用他,你要先安装谷歌插件(谷歌浏览器的话),还得添加驱动。具体操作步骤,请移步百度。 ### url分析 分析完网页结构后,我们来分析下url的构成 前30条数据的 https://search.jd.com/Search?keyword=%E7%B3%96%E6%9E%9C&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&page=1&s=1&click=0 后30条数据的 https://search.jd.com/s_new.php?keyword=%E7%B3%96%E6%9E%9C&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&wq=%E7%B3%96%E6%9E%9C&page=2&s=31&scrolling=y&log_id=1584362139.53979&tpl=1_M&show_items=100007265728,4695858,1227178,4838836,326467,100000424178,100000217809,1083784,4005567,1153605,1153613,4707850,1153610,1178879,4476739,794422,100008420904,100000757536,6338667,100004891346,4476767,30494640062,4491861,3816695,523631,4476753,2210373,679518,3692931,903403 发现两个中,前面构成是基本一致的, keyword:搜索关键字 log_id:是后30个商品的商品id 经过实验,我们发现简化后可用的url:https://search.jd.com/Search?keyword=%E7%B3%96%E6%9E%9C&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&page=1&s=1&click=0 在看下第二页: https://search.jd.com/Search?keyword=%E7%B3%96%E6%9E%9C&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&page=3&s=61&click=0 第三页 (此处省略100字) ... ... 得出url的规律: page = 2*页数 - 1 分析完这些后,就可以进行快乐的编码模式了 ## 代码 直接上代码吧 ``` import time from selenium import webdriver from lxml import etree import urllib import csv import pandas as pd import random #获取页面 def get_page(depth): keyword = "糖果" headers = { "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36" } base_url = 'https://search.jd.com/Search?keyword={}&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&stock=1&page={}' for page_num in range(1,depth): try: start_url = base_url.format(urllib.parse.quote(keyword),page_num*2-1) driver = webdriver.Chrome() driver.get(start_url) driver.execute_script("window.scrollTo(0,document.body.scrollHeight);") #执行下滑到底部的操作 time.sleep(10) #必须休眠,等待获取完全部信息 #获取页面信息 source = driver.page_source # 等同于 response = requests.get(url = start_url,headers=headers) html = etree.HTML(source) item = parse_page(html) write_excel(item) print('爬取第'+str(page_num)+'页时成功!') time.sleep(random.randint(2,6)) except: print('爬取第'+str(page_num)+'页时出错!') continue #解析页面 def parse_page(html): li = html.xpath('//*[@id="J_goodsList"]/ul/li') for one_li in li: yield{ 'price':one_li.xpath('divhttps://img.qb5200.com/download-x/div[2]/strong/i/text()')[0], 'title':get_title(one_li), 'comment_num':one_li.xpath('divhttps://img.qb5200.com/download-x/div[4]/strong/a/text()')[0], 'shop' :get_shop(one_li), 'goods_url':'http://'+one_li.xpath('divhttps://img.qb5200.com/download-x/div[1]/a/@href')[0] } # #获取标题 def get_title(item): title_list = item.xpath('divhttps://img.qb5200.com/download-x/div[3]/a/em/text()') title = ' '.join(title_list) return title #获取店铺名称 def get_shop(item): shop=item.xpath('divhttps://img.qb5200.com/download-x/div[5]/span/a/text()') if len(shop) == 0: return '未知' else: return shop[0] #写入csv文件中 def write_excel(item): good_df = pd.DataFrame(item) good_df.to_csv('./JongDong.csv',mode='a',encoding= 'utf-8-sig') def main(): get_page(50) if __name__ == "__main__": main() ``` 运行结果: ![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1A2JDVeQ-1584365178862)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20200316210020249.png)\]](https://img-blog.csdnimg.cn/2020031621305184.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L01pcmFjbGVfSDEy,size_16,color_FFFFFF,t_70) ![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9zvOfeAK-1584365178865)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20200316210255995.png)\]](https://img-blog.csdnimg.cn/20200316213112766.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L01pcmFjbGVfSDEy,size_16,color_FFFFFF,t_70) ![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sgj7bs6j-1584365178869)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20200316210637929.png)\]](https://img-blog.csdnimg.cn/202003162131359.png) 嗯,很好,都爬取成功了 ![img](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9kc3MxLmJkc3RhdGljLmNvbS83MGNGdVhTaF9RMVlueEdrcG9XSzFIRjZoaHkvaXQvdT0yMjE3NDYyOTg1LDg2NjY4NTg1MCZmbT0yNiZncD0wLmpwZw?x-oss-process=image/format,png) 真的嘛?你不是说一页60,60*49 = 2940.你别欺负我读书少!!! 好吧,我承认是漏了些数据。但我发4,这绝对不是我代码的问题,我测试过爬取单页和爬前几页时是能够爬取完整的。真的只是我家网的问题,没来得及加载完全部数据。虽然我也设置了延时(休眠10s来获取数据),但可能这些时间里刚好碰上网卡情况。下午爬取时候,确实有段时间网特慢。下次,考虑加入retry,让它没爬取完整就重新爬,直到一页的数据爬取完整,变成一个真正合格的爬虫,同时,加入多线程,减少爬取的时间。再说,两千多条也足够用了,不是嘛。嘻嘻(●'◡'●) ## 后记 后面将用今天获得的数据进行分析,解锁**糖果**的密码。(●'◡'●)

加载全部内容

相关教程
猜你喜欢
用户评论