Skip to content

Commit 7b8dcea

Browse files
committed
init 2gis parser
0 parents  commit 7b8dcea

29 files changed

+2152
-0
lines changed

.github/workflows/tests.yml

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
name: Tests
2+
3+
on:
4+
push:
5+
branches: [main, master]
6+
pull_request:
7+
branches: [main, master]
8+
9+
jobs:
10+
tests:
11+
runs-on: ubuntu-latest
12+
13+
strategy:
14+
fail-fast: false
15+
matrix:
16+
php: ['8.3', '8.4']
17+
18+
name: PHP ${{ matrix.php }}
19+
20+
steps:
21+
- name: Checkout code
22+
uses: actions/checkout@v4
23+
24+
- name: Setup PHP
25+
uses: shivammathur/setup-php@v2
26+
with:
27+
php-version: ${{ matrix.php }}
28+
extensions: mbstring, json, curl
29+
coverage: none
30+
31+
- name: Install dependencies
32+
run: composer install --prefer-dist --no-interaction --no-progress
33+
34+
- name: Run tests
35+
run: composer test
36+
37+
code-style:
38+
runs-on: ubuntu-latest
39+
name: Code Style
40+
41+
steps:
42+
- name: Checkout code
43+
uses: actions/checkout@v4
44+
45+
- name: Setup PHP
46+
uses: shivammathur/setup-php@v2
47+
with:
48+
php-version: '8.3'
49+
extensions: mbstring
50+
coverage: none
51+
52+
- name: Install dependencies
53+
run: composer install --prefer-dist --no-interaction --no-progress
54+
55+
- name: Check code style
56+
run: composer cs -- -v
57+
58+
static-analysis:
59+
runs-on: ubuntu-latest
60+
name: Static Analysis
61+
62+
steps:
63+
- name: Checkout code
64+
uses: actions/checkout@v4
65+
66+
- name: Setup PHP
67+
uses: shivammathur/setup-php@v2
68+
with:
69+
php-version: '8.3'
70+
extensions: mbstring
71+
coverage: none
72+
73+
- name: Install dependencies
74+
run: composer install --prefer-dist --no-interaction --no-progress
75+
76+
- name: Run PHPStan
77+
run: composer analyse

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/vendor/
2+
.phpstan.cache/
3+
composer.lock
4+
.phpunit.result.cache

README.md

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
# 2GIS Parser PHP
2+
3+
PHP-библиотека для парсинга данных 2ГИС: организации, отзывы, недвижимость, вакансии.
4+
5+
Работает через [Apify API](https://apify.com/) — запускает акторы и возвращает типизированные DTO.
6+
7+
## Установка
8+
9+
```bash
10+
composer require scraper-apis/2gis-parser
11+
```
12+
13+
## Быстрый старт
14+
15+
```php
16+
use TwoGisParser\Client;
17+
18+
$client = new Client('apify_api_ваш_токен');
19+
20+
// Поиск ресторанов в Москве
21+
$places = $client->scrapePlaces(
22+
query: ['ресторан'],
23+
location: 'Москва',
24+
maxResults: 50,
25+
);
26+
27+
foreach ($places as $place) {
28+
echo "{$place->name} — {$place->address}" . PHP_EOL;
29+
echo "Рейтинг: {$place->rating}, отзывов: {$place->reviewCount}" . PHP_EOL;
30+
31+
if ($place->hasContactInfo()) {
32+
echo "Тел: {$place->getFirstPhone()}" . PHP_EOL;
33+
}
34+
}
35+
```
36+
37+
## Методы
38+
39+
### Организации
40+
41+
```php
42+
$places = $client->scrapePlaces(
43+
query: ['стоматология', 'клиника'],
44+
location: 'Санкт-Петербург',
45+
maxResults: 200,
46+
language: Language::Russian,
47+
country: Country::Russia,
48+
options: [
49+
'filterRating' => 'excellent', // 4.5+
50+
'skipClosedPlaces' => true,
51+
'maxReviews' => 10, // подгрузить отзывы
52+
'filterCardPayment' => true,
53+
],
54+
);
55+
```
56+
57+
### Отзывы
58+
59+
```php
60+
$reviews = $client->scrapeReviews(
61+
startUrls: ['https://2gis.ru/moscow/firm/70000001057394703'],
62+
maxReviews: 100,
63+
reviewsRating: ReviewsRating::Negative, // только 1-2 звезды
64+
reviewsSource: ReviewsSource::TwoGis,
65+
);
66+
67+
foreach ($reviews as $review) {
68+
echo "{$review->authorName}: {$review->rating}/5" . PHP_EOL;
69+
70+
if ($review->hasOfficialAnswer()) {
71+
echo "Ответ: {$review->getOfficialAnswerText()}" . PHP_EOL;
72+
}
73+
}
74+
```
75+
76+
### Недвижимость
77+
78+
```php
79+
$properties = $client->scrapeProperties(
80+
location: 'Казань',
81+
maxResults: 500,
82+
category: PropertyCategory::SaleResidential,
83+
sort: PropertySort::PriceAsc,
84+
options: [
85+
'rooms' => ['2', '3'],
86+
'priceMax' => 15000000,
87+
'notFirstFloor' => true,
88+
],
89+
);
90+
91+
foreach ($properties as $property) {
92+
echo "{$property->name} — {$property->getPriceFormatted()}" . PHP_EOL;
93+
echo "{$property->area} м², этаж {$property->floor}" . PHP_EOL;
94+
}
95+
```
96+
97+
### Вакансии
98+
99+
```php
100+
$jobs = $client->scrapeJobs(
101+
location: 'Новосибирск',
102+
maxResults: 300,
103+
salaryMin: 80000,
104+
);
105+
106+
foreach ($jobs as $job) {
107+
echo "{$job->name} — {$job->orgName}" . PHP_EOL;
108+
echo "Зарплата: {$job->salaryLabel}" . PHP_EOL;
109+
}
110+
```
111+
112+
## Фильтры и перечисления
113+
114+
| Enum | Значения |
115+
|------|----------|
116+
| `Language` | `Auto`, `Russian`, `English`, `Arabic`, `Kazakh`, `Uzbek`, `Kyrgyz`, `Armenian`, `Georgian`, `Azerbaijani`, `Tajik`, `Czech`, `Spanish`, `Italian` |
117+
| `Country` | `Auto`, `Russia`, `Kazakhstan`, `UAE`, `Uzbekistan`, `Kyrgyzstan`, `Armenia`, `Georgia`, `Azerbaijan`, `Belarus`, `Tajikistan`, `SaudiArabia`, `Bahrain`, `Kuwait`, `Qatar`, `Oman`, `Iraq`, `Chile`, `Czechia`, `Italy`, `Cyprus` |
118+
| `RatingFilter` | `None`, `Perfect` (4.9+), `Excellent` (4.5+), `PrettyGood` (4.0+), `Nice` (3.5+), `NotBad` (3.0+) |
119+
| `ReviewsRating` | `All`, `Positive` (4-5), `Negative` (1-2) |
120+
| `ReviewsSource` | `All`, `TwoGis`, `Flamp`, `Booking` |
121+
| `PropertyCategory` | `SaleResidential`, `SaleCommercial`, `RentResidential`, `RentCommercial`, `DailyRent` |
122+
| `PropertySort` | `Default`, `PriceAsc`, `PriceDesc`, `AreaAsc`, `AreaDesc` |
123+
124+
## Конфигурация
125+
126+
```php
127+
use TwoGisParser\Client;
128+
use TwoGisParser\Config;
129+
130+
$client = new Client('токен', new Config(
131+
apiToken: 'токен',
132+
placesActorId: 'zen-studio/2gis-places-scraper-api', // по умолчанию
133+
reviewsActorId: 'zen-studio/2gis-reviews-scraper',
134+
propertyActorId: 'zen-studio/2gis-property-scraper',
135+
jobsActorId: 'zen-studio/2gis-jobs-scraper',
136+
timeout: 900,
137+
));
138+
```
139+
140+
## Обработка ошибок
141+
142+
```php
143+
use TwoGisParser\Exception\ApiException;
144+
use TwoGisParser\Exception\RateLimitException;
145+
146+
try {
147+
$places = $client->scrapePlaces(query: ['кафе'], location: 'Алматы');
148+
} catch (RateLimitException $e) {
149+
sleep($e->retryAfter);
150+
// повторить запрос
151+
} catch (ApiException $e) {
152+
echo "Ошибка API: {$e->getMessage()}" . PHP_EOL;
153+
}
154+
```
155+
156+
## Требования
157+
158+
- PHP 8.3+
159+
- Токен [Apify API](https://console.apify.com/account/integrations)
160+
161+
## Лицензия
162+
163+
MIT

composer.json

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"name": "scraper-apis/2gis-parser",
3+
"description": "PHP client library for scraping 2GIS data (places, reviews, property, jobs) using Apify actors",
4+
"type": "library",
5+
"license": "MIT",
6+
"require": {
7+
"php": "^8.3",
8+
"guzzlehttp/guzzle": "^7.0"
9+
},
10+
"require-dev": {
11+
"pestphp/pest": "^4.0",
12+
"laravel/pint": "^1.0",
13+
"phpstan/phpstan": "^1.0"
14+
},
15+
"autoload": {
16+
"psr-4": {
17+
"TwoGisParser\\": "src/"
18+
}
19+
},
20+
"autoload-dev": {
21+
"psr-4": {
22+
"TwoGisParser\\Tests\\": "tests/"
23+
}
24+
},
25+
"scripts": {
26+
"test": "pest",
27+
"cs": "pint --test",
28+
"cs:fix": "pint",
29+
"analyse": "phpstan analyse"
30+
},
31+
"config": {
32+
"sort-packages": true,
33+
"allow-plugins": {
34+
"pestphp/pest-plugin": true
35+
}
36+
}
37+
}

phpstan.neon

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
parameters:
2+
level: 8
3+
paths:
4+
- src
5+
tmpDir: .phpstan.cache

phpunit.xml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
4+
bootstrap="vendor/autoload.php"
5+
colors="true">
6+
<testsuites>
7+
<testsuite name="Tests">
8+
<directory>tests</directory>
9+
</testsuite>
10+
</testsuites>
11+
<source>
12+
<include>
13+
<directory>src</directory>
14+
</include>
15+
</source>
16+
</phpunit>

pint.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"preset": "laravel"
3+
}

0 commit comments

Comments
 (0)