目前爬蟲基本思想就是進(jìn)入一個網(wǎng)站商品列表頁并進(jìn)入具體商品鏈接剪撬,爬取商品詳情摄乒。這次選擇的是國內(nèi)某知名生活服務(wù)網(wǎng)站。一段時間的學(xué)習(xí)后残黑,運(yùn)用chrome尋找需求元素已能得心應(yīng)手馍佑,但是實際操作中依然遇到一些問題。
主要問題
- 在商品詳情頁中萍摊,不同來源類型的商品有不同的css樣式挤茄,這使得select()不能直接適用,因此在商品列表頁需要進(jìn)行將爬取的商品詳情鏈接分為兩類冰木,分別爬取穷劈。
- 在其中一類笼恰,個別需要爬取的信息中是通過js的方式查看的,需要通過不同的方式獲取這部分的內(nèi)容
- 個別字符串信息的處理出現(xiàn)了一些問題
最終效果
在sublime python編譯環(huán)境下爬取的一頁數(shù)據(jù)歇终,一共有三十七個商品社证,但是有時js獲取點(diǎn)擊量(hit)的方法會行不通。
Paste_Image.png
我的代碼
在sublime 的python環(huán)境下爬取了一頁商品信息评凝,一共有37個追葡。保存在dict中,以方便之后在數(shù)據(jù)庫中的操作奕短。
# -*- coding: utf-8 -*-
import requests,time
from bs4 import BeautifulSoup
headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36'
}
def main():
url='***********'
web=requests.get(url,headers=headers)
soup=BeautifulSoup(web.text, 'lxml')
hrefs_zz=soup.select(' tr.zzinfo td.img a') #所有鏈接
hrefs_jz=soup.select(' tr.zzinfo.zzjingzhun td.img a') #精準(zhǔn)推廣的鏈接
count=0 #為每個商品info計數(shù)
if hrefs_zz: #是不是為空
print len(hrefs_zz)
for href in hrefs_zz:
#print href
count=count+1
print count, '--->'
link=href.get('href')
getsingle_info(link)
time.sleep(2)
else:
print 'heheha'
def getsingle_info(href): #zz下
web=requests.get(href,headers=headers)
soup=BeautifulSoup(web.text, 'lxml')
#titles=soup.title.text # 網(wǎng)頁title標(biāo)簽內(nèi)容與商品詳情標(biāo)簽相同
titles=soup.select(' h1.info_titile ')
if titles:
pass
else:
get_jzsingle_info(href)
return
cates=soup.select('.breadCrumb > span')
prices=soup.select('span.price_now > i')
addrs=soup.select('div.palce_li > span > i')
hits=soup.select('.look_time')
data={
'cate': [cates[i].get_text().strip() for i in range(len(cates))], #s.strip(rm) rm為空時宜肉,默認(rèn)刪除空白(\r \n \t)
#cate[i].stripped_strings不對其列表化時 返回的就是一個內(nèi)存對象
'title': titles[0].text,
'price': prices[0].text,
'addr': addrs[0].text,
'hit': hits[0].text
}
print data,'\n------------------\n'
def get_jzsingle_info(url):
web=requests.get(url,headers=headers)
soup=BeautifulSoup(web.text, 'lxml')
cates=soup.select('.breadCrumb > span')
#print cates,'\n'
titles=soup.select('.col_sub.mainTitle > h1')
#print titles,'\n'
prices=soup.select('span.price.c_f50 ')
#print prices,'\n'
addrs=soup.select('span.c_25d > a ')
hits=soup.select(' #totalcount ')
#print addrs, '\n'
data={
'cate': [cates[i].get_text().strip() for i in range(len(cates))],
'title': titles[0].text if titles else None,
'price': prices[0].text if prices else None,
'addr': addrs[0].text if addrs else None,
'hit': gethits(url)
}
print data,'\n------------------\n'
def gethits(url):
keyword=url.split('/')[-1].strip('x.shtml') #得到每個商品的id
api='***********r?infoid={}'.format(keyword)
headers={'Referer': url}
js= requests.get(api,headers=headers)
hits=js.text.split('=')[-1]
return hits
if __name__ == '__main__':
main()
總結(jié)
- 網(wǎng)頁元素中運(yùn)用class 與 id 可以唯一尋找,并且可以不用 > 來更快的選擇子類標(biāo)簽
- 由于存在兩種類型的商品詳情頁面翎碑,我的思路是如果其中一種select()方式選擇的為空list谬返,就進(jìn)入另一個爬取商品信息函數(shù)。這樣做的好處是分別獲得不同商品類型的信息而不是None
- js 中的內(nèi)容是根據(jù)api來獲得的 日杈,還需要添加一個referer(來源地址)遣铝,為了網(wǎng)站的反爬取,同時需要偽裝成瀏覽器莉擒。
- 學(xué)習(xí)了strip() 與 split() 兩個字符串處理函數(shù)