python爬取京东手机参数_python爬取京东数据

实现工具

scrapy

BeautifulSoup

requests

原理分析

打开京东首页,搜索裤子将会打开裤子页面如:这里,这个页面的数据就是我们要将要获取的。

我们可以看到这个页面当我们往下拉的时候将会看到图片在不停的加载,这就是ajax,但是当我们下拉到底的时候就会看到页面又多加载了30条数据,我们打开chrome的调试工具,查找页面元素时可以看到每条裤子的信息都在

1

这个标签中,如下图:

接着我们打开网页源码就会发现其实网页源码只有前30条的数据,后面30条的数据找不到,因此这里就会想到ajax,一种异步加载的方式,于是我们就要开始抓包了,我们打开chrome按F12,点击上面的NetWork,然后点击XHR,这个比较容易好找,下面开始抓包,如下图:

从上面可以找到请求的url,发现有很长的一大段,我们试着去掉一些看看可不可以打开,简化之后的url=’https://search.jd.com/s_new.php?keyword=%E8%A3%A4%E5%AD%90&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&offset=3&wq=%E8%A3%A4%E5%AD%90&page={0}&s=26&scrolling=y&pos=30&show_items={1}’,这里的showitems是裤子的id,page是翻页的,可以看出来我们只需要改动两处就可以打开不同的网页了,这里的page很好找,你会发现一个很好玩的事情,就是主网页的page是奇数,但是异步加载的网页中的page是偶数,因此这里只要填上偶数就可以了,但是填奇数也是可以访问的。这里的show_items就是id了,我们可以在页面的源码中找到,通过查找可以看到id在li标签的data-pid中,详情请看下图

上面我们知道怎样找参数了,现在就可以撸代码了

代码讲解

我们通过requests获取网页源码

def get_html(self):

res = requests.get(self.url, headers=self.headers)

html = res.text

return html #返回的源代码

1

2

3

4

defget_html(self):

res=requests.get(self.url,headers=self.headers)

html=res.text

returnhtml#返回的源代码

我们获取到网页源码后,通过BeautifulSoup对源码进行分析。获取得到异步加载的url中的参数show_items,就是li标签中的data-pid,代码如下:

def get_pids(self):

html = self.get_html()

soup = BeautifulSoup(html, 'lxml') #创建BeautifulSoup对象

lis = soup.find_all("li", class_='gl-item') #查找li标签

for li in lis:

data_pid = li.get("data-pid") #得到li标签下的data-pid

if (data_pid):

self.pids.add(data_pid) #这里的self.pids是一个集合,用于过滤重复的

1

2

3

4

5

6

7

8

defget_pids(self):

html=self.get_html()

soup=BeautifulSoup(html,'lxml')#创建BeautifulSoup对象

lis=soup.find_all("li",class_='gl-item')#查找li标签

forliinlis:

data_pid=li.get("data-pid")#得到li标签下的data-pid

if(data_pid):

self.pids.add(data_pid)#这里的self.pids是一个集合,用于过滤重复的

下面就是获取前30张图片的url了,也就是主网页上的图片,其中一个问题是img标签的属性并不是一样的,也就是源码中的img中不都是src属性,一开始已经加载出来的图片就是src属性,但是没有加载出来的图片是data-lazy-img,因此在解析页面的时候要加上讨论。代码如下:

def get_src_imgs_data(self):

html = self.get_html()

soup = BeautifulSoup(html, 'lxml')

divs = soup.find_all("div", class_='p-img') # 图片

# divs_prices = soup.find_all("div", class_='p-price') #价格

for div in divs:

img_1 = div.find("img").get('data-lazy-img') # 得到没有加载出来的url

img_2 = div.find("img").get("src") # 得到已经加载出来的url

if img_1:

print img_1

self.sql.save_img(img_1)

self.img_urls.add(img_1)

if img_2:

print img_2

self.sql.save_img(img_2)

self.img_urls.add(img_2)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

defget_src_imgs_data(self):

html=self.get_html()

soup=BeautifulSoup(html,'lxml')

divs=soup.find_all("div",class_='p-img')# 图片

# divs_prices = soup.find_all("div", class_='p-price')   #价格

fordivindivs:

img_1=div.find("img").get('data-lazy-img')# 得到没有加载出来的url

img_2=div.find("img").get("src")# 得到已经加载出来的url

ifimg_1:

printimg_1

self.sql.save_img(img_1)

self.img_urls.add(img_1)

ifimg_2:

printimg_2

self.sql.save_img(img_2)

self.img_urls.add(img_2)

第一页的数据我们都找到了,我们下面开始获取第二页数据

def get_extend_imgs_data(self):

# self.search_urls=self.search_urls+','.join(self.pids)

self.search_urls = self.search_urls.format(str(self.search_page), ','.join(self.pids)) #拼凑url,将获得的单数拼成url,其中show_items中的id是用','隔开的,因此要对集合中的每一个id分割,page就是偶数,这里直接用主网页的page加一就可以了

print self.search_urls

html = requests.get(self.search_urls, headers=self.headers).text #请求

soup = BeautifulSoup(html, 'lxml')

div_search = soup.find_all("div", class_='p-img') #解析

for div in div_search:

img_3 = div.find("img").get('data-lazy-img') #这里可以看到分开查找img属性了

img_4 = div.find("img").get("src")

if img_3: #如果是data-lazy-img

print img_3

self.sql.save_img(img_3) #存储到数据库

self.img_urls.add(img_3) #用集合去重

if img_4: #如果是src属性

print img_4

self.sql.save_img(img_4)

self.img_urls.add(img_4)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

defget_extend_imgs_data(self):

# self.search_urls=self.search_urls+','.join(self.pids)

self.search_urls=self.search_urls.format(str(self.search_page),','.join(self.pids))#拼凑url,将获得的单数拼成url,其中show_items中的id是用','隔开的,因此要对集合中的每一个id分割,page就是偶数,这里直接用主网页的page加一就可以了

printself.search_urls

html=requests.get(self.search_urls,headers=self.headers).text#请求

soup=BeautifulSoup(html,'lxml')

div_search=soup.find_all("div",class_='p-img')#解析

fordivindiv_search:

img_3=div.find("img").get('data-lazy-img')#这里可以看到分开查找img属性了

img_4=div.find("img").get("src")

ifimg_3:#如果是data-lazy-img

printimg_3

self.sql.save_img(img_3)#存储到数据库

self.img_urls.add(img_3)#用集合去重

ifimg_4:#如果是src属性

printimg_4

self.sql.save_img(img_4)

self.img_urls.add(img_4)

以上就是我们这个爬虫的核心代码,但是还是要考虑速度的问题,这里使用了多线程,直接每一页面开启一个线程。

扩展

写到这里可以看到搜索首页的网址中keyword和wq都是你输入的词,如果你想要爬取更多的信息,可以将这两个词改成你想要搜索的词即可,直接将汉字写上,在请求的时候会自动帮你编码的,我也试过了,可以抓取源码的,如果你想要不断的抓取,可以将要搜索的词写上文件里,然后从文件中读取就可以了。

参考文档:http://www.cnblogs.com/Chenjiabing/p/6907440.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值