下载地址:https://www.pan38.com/share.php?code=pvvmX 提取码:7789 【仅供学习测试用途】
Auto.js实现美团商家数据的自动化采集,包含页面解析、数据提取和存储功能。使用时需要开启无障碍服务,建议在模拟器环境测试学习。核心采用控件层级定位技术,通过深度遍历获取商家信息。数据保存为CSV格式便于分析,包含反检测的随机延迟设计,当然仅供学习测试用哈。
// 配置参数
const config = {
scrollDelay: 1500, // 滚动间隔
maxPage: 5, // 最大翻页数
outputFile: "/sdcard/meituan_data.csv"
};
// 主采集流程
function main() {
launchApp("美团");
sleep(3000);
let results = [];
for(let i=0; i<config.maxPage; i++) {
let items = captureCurrentPage();
results = results.concat(items);
scrollDown();
sleep(config.scrollDelay);
}
saveToCSV(results);
}
// 页面数据采集
function captureCurrentPage() {
let items = [];
let shops = className("android.view.View").depth(15).find();
shops.forEach(shop => {
try {
let obj = {
name: shop.findOne(className("android.widget.TextView").depth(16)).text(),
score: parseFloat(shop.findOne(className("android.widget.TextView").depth(18)).text()),
address: shop.findOne(className("android.widget.TextView").depth(20)).text(),
phone: extractPhone(shop)
};
items.push(obj);
} catch(e) { /* 忽略采集错误 */ }
});
return items;
}
提取联系电话
function extractPhone(shop) {
let phoneBtn = shop.findOne(textMatches(/[0-9]{3}-?[0-9]{4}-?[0-9]{4}/));
if(phoneBtn) {
phoneBtn.click();
sleep(500);
let phone = textMatches(/1[3-9]\d{9}/).findOne().text();
back();
return phone;
}
return "";
}
// 保存CSV文件
function saveToCSV(data) {
let csv = "商家名称,评分,地址,电话\n";
data.forEach(item => {
csv += "${item.name}",${item.score},"${item.address}","${item.phone}"\n;
});
files.write(config.outputFile, csv);
}
// 模拟滚动
function scrollDown() {
swipe(device.width/2, device.height0.8,
device.width/2, device.height0.2, 500);
}
import org.apache.poi.ss.usermodel.;
import org.apache.poi.xssf.usermodel.;
import java.io.;
import java.util.;
public class ExcelProcessor {
private XSSFWorkbook workbook;
private XSSFSheet sheet;
public void createWorkbook() {
workbook = new XSSFWorkbook();
sheet = workbook.createSheet("DataSheet");
// 创建标题行样式
CellStyle headerStyle = workbook.createCellStyle();
Font headerFont = workbook.createFont();
headerFont.setBold(true);
headerStyle.setFont(headerFont);
// 创建数据行
Row headerRow = sheet.createRow(0);
String[] headers = {"ID","名称","价格","库存"};
for(int i=0; i<headers.length; i++) {
Cell cell = headerRow.createCell(i);
cell.setCellValue(headers[i]);
cell.setCellStyle(headerStyle);
}
}
public void addData(List<Product> products) {
int rowNum = 1;
for(Product p : products) {
Row row = sheet.createRow(rowNum++);
row.createCell(0).setCellValue(p.getId());
row.createCell(1).setCellValue(p.getName());
row.createCell(2).setCellValue(p.getPrice());
row.createCell(3).setCellValue(p.getStock());
}
autoSizeColumns();
}
private void autoSizeColumns() {
for(int i=0; i<4; i++) {
sheet.autoSizeColumn(i);
}
}
public void addChart() {
Drawing drawing = sheet.createDrawingPatriarch();
ClientAnchor anchor = drawing.createAnchor(0,0,0,0,5,1,15,15);
XSSFChart chart = drawing.createChart(anchor);
ChartLegend legend = chart.getOrCreateLegend();
legend.setPosition(LegendPosition.BOTTOM);
// 图表数据配置
ChartDataSource<String> xs = DataSources.fromStringCellRange(
sheet, new CellRangeAddress(1, 10, 0, 0));
ChartDataSource<Number> ys = DataSources.fromNumericCellRange(
sheet, new CellRangeAddress(1, 10, 2, 2));
chart.plot(xs, ys);
}
public void saveToFile(String path) throws IOException {
try(FileOutputStream out = new FileOutputStream(path)) {
workbook.write(out);
}
}
public static class Product {
private int id;
private String name;
private double price;
private int stock;
// getters/setters省略
}
}