那么先看一下需求
获取某个关键词,例如‘土豆/水饺/裤子’
然后根据关键词获得所有有关于此类商品的信息
并在基础上进行简单的剔除无效信息的操作,
例如我想获取所有农产品土豆的信息,但是如果键入土豆无疑会获得类似削皮刀之类的东西
那么这时候我们就需要将他剔除,感谢京东,对物品的分类信息做的很细腻,我们可以直接获取到京东的商品信息,从而进行判断
但是例如搜索猪肉时。是会有许多种类的,此时我们就没法做到很好的剔除工作,如果有建议的朋友可以指导一下
class new_Thread(threading.Thread):
def __init__(self,Dic):
threading.Thread.__init__(self)
self.Dic = Dic
def run(self):
self.result = getxinxi(self.Dic)
def get_result(self):
return self.result
那么接下来开始对京东的搜索过程进行分析
以土豆作为关键字:
https://search.jd.com/Search?keyword=%E5%9C%9F%E8%B1%86&enc=utf-8&wq=&pvid=8591a7d46ea8404aba95e8f0613fa1de
经过尝试可以吧pvid给扔了
那https://search.jd.com/Search?keyword=%E5%9C%9F%E8%B1%86&enc=utf-8&wq=&
keyword显然是土豆,那么我们可以在这个网页获得什么呢?
url = 'https://search.jd.com/Search?keyword=%E5%9C%9F%E8%B1%86&enc=utf-8'
content =requests.get(url).text
selector = etree.HTML(content)
links = selector.xpath(".//*[@id='J_goodsList']/ul/li/div/div[1]/a/@href")
以这个为例
我们获得了网页上商品的href属性,即链接
但是一页有60个商品,这里只有30条,很明显网页采取了动态加载。
此时我们开始抓包
https://search.jd.com/s_new.php?keyword=%E5%9C%9F%E8%B1%86&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&stock=1&page=2&s=31&scrolling=y&log_id=1501053622.70266&tpl=1_M&show_items=4181290,5187466,2902583,3742735,4019068,4342735,3876067,13521003503,13180188297,2329545,3382260,13461460252,1595871447,10272539167,10429929292,13239830319,3037821,12046382476,12160864074,12883026171,12325862734,13139706111,13324208094,12657657243,12065839723,10931189270,10723290126,14193195383,11829758955,11828453656
同样,这是url
根据头信息可以轻松获得 Referer
这个show_items又可以从上30条信息获取到,随后只要更换page的值即可
urlbase = 'https://search.jd.com/s_new.php?keyword=%s&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&wq=%s&stock=1&page=%d&s=28&scrolling=y&log_id=%s'
for i in range(1,40):
header = {
'Referer':'https://search.jd.com',
}
content = requests.get(urlbase%(Str,Str,i,getstr(Str)),headers=header).text
这个接口中返回的数据是需要进行处理的,如何获得我们想要的信息呢?
首先确认一下有效信息:
商品的title 标题,href链接 以及价格price
在价格这边我没法在商品的网站找到任何信息,估计是没有的
pat_sta = re.compile(''%Dic[key]['id'])
items = re.findall(pat_price,content)
if items!=[]:
Dic[key]['price'] = items[0]
这一块用的是正则表达式
匹配到了这几个属性
id即为商品的id,是唯一的
接下来 就是具体的每个商品的信息了
这个很简单,因为属性都是暴露的
def getxinxi(Dic):
Dict = Dic.copy()
for i in Dic.keys():
time.sleep(1)
try:
content = requests.get('https:'+Dic[i]['href']).text
selector = etree.HTML(content)
#links = selector.xpath("body/div[8]/div[2]/div[1]/div[2]/div[1]/div[1]/ul[2]/li/text()")
links = selector.xpath(".//*[@id='detail']/div[2]/div[1]/div[1]/ul[2]/li/text()")
for link in links:
items_link = link.split(u':')
if items_link.__len__()==2:
Dict[i][items_link[0]] = items_link[1]
links_dianpu = selector.xpath(".//*[@id='parameter-brand']/li/a/text()")
if links_dianpu!=[]:
Dict[i][u'店铺'] = links_dianpu[0]
header1 = {
'Referer': 'https://item.jd.com',
}
url = 'https://club.jd.com/comment/productCommentSummaries.action?referenceIds=%s'
content2 = requests.get(url%Dict[i]['id'],headers=header1).text
Str1 = json.loads(content2)
Dict[i][u'allcount'] = str(Str1[u'CommentsCount'][0][u'CommentCount'])+'+'
Dict[i][u'goodcount'] = str(Str1[u'CommentsCount'][0][u'GoodCount'])+'+'
Dict[i][u'genecount'] = str(Str1[u'CommentsCount'][0][u'GeneralCount'])+'+'
Dict[i][u'poorcount'] = str(Str1[u'CommentsCount'][0][u'PoorCount'])+'+'
except:
print 'Error'+Dic[i]['title']
return Dict
返回的字典是带有商品信息的
那么还有一个值得参考的部分就是商品的评论信息
也写在上面的代码里了,具体是如何获取的和第一步类似,直接抓到评论的url就行了
大家可以拿去跑了试一下
这是获取log_id的函数
def getstr(s):
html = requests.get('https://search.jd.com/Search?keyword=%s&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&wq=%s'%(s,s)).text
soup = BeautifulSoup(html, 'lxml')
lis = soup.find_all("li", class_='gl-item')
str1 = ''
for li in lis:
data_pid = li.get("data-sku")
str1=str1+str(data_pid)+','
return str1
s是 土豆或者是别的的关键词
没用数据库我存在了excel里,给大家看一下效果图吧
最主要的几个实现代码都在上面了,其他就是如何多线程操作的,就不具体放上来了
谢谢~