最近想写点东西,然后见到群里在咨询爬京东的方法,也就抱着试一试的情况写一下,发现其实是个静态网站,并不是很麻烦;
主要使用的是request库和lxml的etree类,以及使用xlwt保存文件;
1. 首先导入库
import requests
import xlwt
from lxml import etree
复制代码
为保存文件做准备:
因为我是需要爬取这些数据,所以参考几个手机类型,建立表格
wb = xlwt.Workbook()
sheet = wb.add_sheet('sh')
i = 0 #行
l = 1 #列
title = {
"商品链接":0,
"价格":1,
"商品名称":2,
"商品编号":3,
"商品毛重":4,
"商品产地":5,
"运行内存":6,
"后摄主摄像素":7,
"前摄主摄像素":8,
"分辨率":9,
"充电器":10,
"系统":11,
"充电功率":12,
"机身内存":13
}
for key in title:
sheet.write(i,title[key],key)
复制代码
后面运行的时候出现了# Attempt to overwrite cell: sheetname=\‘sh\‘ rowx=1 colx=5 问题
但是是因为这里的地方错误,所以在这里备注一下:
问题出现原因:
出现这个错误提示,一般是代码执行了向已经有数据的单元格中又写入数据,如果你并没有这样的想法,那么很大可能是你的行或者列在增长时出错了,建议检查一下就能解决。
如果找不出问题,cell_overwrite_ok=True
像这样:
wb = xlwt.Workbook()
sheet = wb.add_sheet('sh',cell_overwrite_ok=True)
复制代码
这样的话,会覆盖写入数据
完整代码
这里的cookie 自己复制自己的就好了
headers = {
'user-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.87 Safari/537.36',
'cookie':'--------------------------------------','Connection':'colse'
}
复制代码
下面的abcd是随意取的,a是页数,实际情况中,我们浏览的一页,相当于数据中的2页,如图,我们在查看第二页的时候,会直接跳到page=3,其实每页的数据是30条,而我们在网页中,每一页能够浏览的数据是60条;这是因为当我们浏览往下滑的时候,page会增加1,这时候数据就会把后面的30条加载出来;
这里的b是查询内容
c和d是用来存储链接与价格的,将每一页的链接和价格存入这两个表格;这里应该还能继续优化;
i+=1是因为我们后续写入文件应该从第一行开始写了,这也是我出现# Attempt to overwrite cell: sheetname=\‘sh\‘ rowx=1 colx=5 问题
的原因!
timeout=(3,7)
是因为我在调试的过程中,出现了Connection aborted.', TimeoutError(10060, '由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。', None, 10060, None)
问题,timeout(3,7)表示的连接时间是3秒,响应时间是7秒。
a = 10 #页数,一页30条数据,这里定为10页
b = '手机' #查询内容
c = []
d = []
i+=1
for page in range(a):
url = f'https://search.jd.com/Search?keyword={b}&page={page}'
resp = requests.get(url,headers = headers,timeout=(3,7))
html = etree.HTML(resp.text)
divs = html.xpath('//*[@id="J_goodsList"]/ul/li/div/div[1]/a/@href')
prices = html.xpath('//*[@id="J_goodsList"]/ul/li/div/div[3]/strong/i/text()')
for div in divs:
c.append(div) # 将链接存储
for price in prices:
d.append(price) # 将价格存储
for ch in range(len(c)):
l = 0 # l表示列(这是字母l)
sheet.write(i,l,c[ch])
l+=1
sheet.write(i,l,d[ch])
l+=1
# 开始对详情页爬取
url = f'https:{c[ch]}'
resp2 = requests.get(url,headers = headers)
html2 = etree.HTML(resp2.text)
for s in range(1,20):
div = f'//*[@id="detail"]/div[2]/div[1]/div[1]/ul[3]/li[{s}]/text()'
data = html2.xpath(div)
for da in data:
data_list = da.split(':')
if data_list[0] in title:
l = title[data_list[0]]
val = data_list[1]
sheet.write(i,l,val)
i+=1
wb.save('jd.xls')
复制代码
详情页爬取
for s in range(1,20):
因为每一页的情况不一样,所以我采取20个数据以保证无遗漏,然后对采集到的数据根据’:’进行分割;通过对照标签添加数据;
注意加在请求头中添加'Connection':'colse'
或者后面添加resp.close()
运行完成后查看一下: