本人小白一枚,
编码太low,暂时先跑起来后期再做修改
from selenium.webdriver.chrome.options import Options
from selenium import webdriver
import requests
import Geohash
import urllib.request
import urllib.parse
import json
import random
from time import sleep
# 各个市区名称 https://www.ele.me/restapi/shopping/v1/cities
class ElemeSpider():
def get_city(slef):
url_city = 'https://www.ele.me/restapi/shopping/v1/cities'
headers = {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36",
}
request = urllib.request.Request(url=url_city, headers=headers)
slef.json_text = urllib.request.urlopen(request).read().decode()
slef.json_obj = json.loads(slef.json_text) #获取所有城市json数据 并转为字典格式
slef.objs = []
for i in slef.json_obj:
for j in slef.json_obj[i]:
slef.objs.append(j)
#{'abbr': 'AX', 'id': 608, 'latitude': 38.935349, 'longitude': 115.935638, 'name': '安新', 'pinyin': 'anxin'}
# 城市参数 有 latitude 和 longitude 这两个参数是 经纬度 用于后面的url输入 以及 经纬度计算
slef.city_all = []
for city in slef.objs: slef.city_all.append(city['name'])
slef.name = input("请输入您要下载数据的城市:")
while slef.name not in slef.city_all:
name = input('输入错误!!! 请重新输入:')
for slef.ci in slef.objs:
if slef.ci['name'] == slef.name:
slef.latitude = slef.ci['latitude']
slef.longitude = slef.ci['longitude']
return slef.latitude, slef.longitude, slef.name
def get_page(slef):
## 整合url 获取json数据
slef.url = 'https://www.ele.me/restapi/shopping/restaurants?extras%5B%5D=activities&geohash={geohash}&latitude={latitude}&limit=24&longitude={longitude}&offset={offset}&terminal=web'.format(
geohash=slef.g, latitude=slef.latitude, offset=slef.limit_num, longitude=slef.longitude)
headers = {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36",
"Cookie": "******* 可用开发者工具捕捉也可用 Fiddler获取 ********",
}
re = json.loads(requests.get(slef.url, headers=headers).text)
print('正在载入中......')
##写入文件
f = open('elm.txt', 'w', encoding='utf-8')
for i in re:
f.write('----------------------------------------\n')
f.write('店名:' + str(i.get('name')) + '\n')
f.write('月销售量:' + str(i.get('recent_order_num')) + '\n')
f.write('地址:' + str(i.get('address')) + '\n')
f.write('配送费:' + str(i.get('float_delivery_fee')) + '\n')
f.write('配送时间:' + str(i.get('order_lead_time')) + '\n')
f.write('距离:' + str(i.get('distance')) + '\n')
f.write('起送价:' + str(i.get('float_minimum_order_amount')) + '\n')
f.write('评分:' + str(i.get('rating')) + '\n')
f.close()
print('爬取完毕')
def selen_auto(slef):
"""可使用无头,直接自动化操作谷歌会更直观点,的登录的时候好操作"""
# https://www.ele.me/place/ws105tg30kcy?latitude=22.531784&longitude=114.064535
# 先使用无头浏览器动态加载页面,而后记录最终数据量的标签汇总,记录limit的值
# 根据 limit进行爬取,非无头爬取
# chrome_options = Options()
# chrome_options.add_argument('--headless')
# chrome_options.add_argument('--disable-gpu')
# 驱动路径
# path = r'D:\workon_home\venv_scrapt\Scripts\chromedriver.exe'
# 创建浏览器对象
# browser = webdriver.Chrome(executable_path=path, chrome_options=chrome_options)
browser = webdriver.Chrome()
slef.g = Geohash.encode(slef.latitude, slef.longitude)
phone = str(input('请输入手机号码进行登录:'))
url_log= 'https://h5.ele.me/login/#redirect=https%3A%2F%2Fwww.ele.me%2Fhome%2F'
browser.get(url_log)
print('获取登陆页面')
sleep(random.uniform(1, 3))
browser.find_element_by_xpath('//input[@placeholder="手机号"]').send_keys(phone[:3])#模拟输入手机号前三位
sleep(random.uniform(1, 3))
browser.find_element_by_xpath('//input[@placeholder="手机号"]').send_keys(phone[3:7])#模拟输入手机号中间三
sleep(random.uniform(1, 3))
browser.find_element_by_xpath('//input[@placeholder="手机号"]').send_keys(phone[7:])#输入手机号后四位
sleep(random.uniform(1, 3))
print('手机号码输入完毕!')
browser.find_element_by_xpath('/html/body/div[1]/div[1]/div[2]/form/section[1]/button').click() #点击获取验证码
sleep(random.uniform(1, 3))
print('点击验证码!')
try:
code_jpg = browser.find_element_by_xpath('/html/body/div[1]/div[1]/div[2]/div/div')#是否有图形验证码
code_root = browser.find_element_by_xpath('/html/body/div[1]/div[1]/div[2]/div/div')#是否有跟状验证码
# //*[@id="nc_1_n1z"]
#判断 如果有图形验证码
if code_jpg:
print('图形验证码已保存!')
browser.save_screenshot("图形验证码.png")
sleep(random.uniform(2,3))
img_code = input('请输入图形验证码:')
browser.find_element_by_xpath('/html/body/div[1]/div[1]/div[2]/div/div/div[1]/div/input').send_keys(img_code[:2])
sleep(random.uniform(1,2))
browser.find_element_by_xpath('/html/body/div[1]/div[1]/div[2]/div/div/div[1]/div/input').send_keys(img_code[2:])
sleep(random.uniform(1,2))
# 点击确定
browser.find_element_by_xpath('/html/body/div[1]/div[1]/div[2]/div/div/div[2]/button[2]').click()
sleep(random.uniform(1,2))
elif code_root:
#条形验证码未添加
print('正在进行条形验证码验证!')
except Exception as e:
print(e)
finally:
sleep(random.uniform(1,3))
send_code = str(input('请输入验证码:'))
browser.find_element_by_xpath('/html/body/div[1]/div[1]/div[2]/form/section[2]/input').send_keys(send_code)#填写验证码
sleep(random.uniform(1,3))
browser.find_element_by_xpath('/html/body/div[1]/div[1]/div[2]/form/button').click() #点击登陆按钮
print('点击登陆按钮')
sleep(random.uniform(1,5))
# 经纬计算这个库进行 geohash计算
slef.g = Geohash.encode(slef.latitude, slef.longitude)
url_ = 'https://www.ele.me/place/{geohash}?latitude={latitude}&longitude={longitude}'.format(
geohash=slef.g, latitude=slef.latitude, longitude=slef.longitude)
browser.get(url_)
sleep(random.uniform(1, 3))
##模拟鼠标向下滚动
m = 0
while m < 6 :
n = 0
while n < 6:
#模拟鼠标滚动向下,距离3000
browser.execute_script("window.scrollBy(0,3000)")
sleep(random.uniform(1, 3))
n += 1
print('滚动第{}次'.format(n))
try:
click_gengduo = browser.find_element_by_id('fetchMoreRst') # 判断是否有点击更多按钮
m += 1
if click_gengduo:
sleep(random.uniform(1, 3))
print('点击更多按钮第{}次'.format(m))
browser.find_element_by_id('fetchMoreRst').click()
sleep(random.uniform(1, 3))
except Exception as e:
print('没有点击按钮出现,跳出循环')
print(e)
break
print('查看商家个数,定位中...')
slef.limit_len = browser.find_elements_by_xpath('//a[contains(@href, "/shop")]')
sleep(random.uniform(1, 3))
slef.limit_num = len(slef.limit_len)
print('{name}地区的商家总共有:{len}家!'.format(name = slef.name,len=slef.limit_num))
browser.quit()
if __name__ == '__main__':
eleme = ElemeSpider()
eleme.get_city() #首先获取所有城市地区
eleme.selen_auto()
eleme.get_page()
向各位大佬们学习!