feat: initail drug crawling

This commit is contained in:
2026-05-16 23:30:16 +03:30
parent 42938fb651
commit 28f0c868d5
8 changed files with 94 additions and 6 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="17" />
<bytecodeTargetLevel target="21" />
</component>
</project>
+8
View File
@@ -4,6 +4,14 @@
<selectionStates>
<SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2026-05-15T13:26:47.825150Z">
<Target type="DEFAULT_BOOT">
<handle>
<DeviceId pluginId="LocalEmulator" identifier="path=/Users/amirmahdi/.android/avd/Pixel_3a_API_33_arm64-v8a.avd" />
</handle>
</Target>
</DropdownSelection>
<DialogSelection />
</SelectionState>
</selectionStates>
</component>
+1 -2
View File
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
+4
View File
@@ -88,4 +88,8 @@ dependencies {
implementation(libs.androidx.room.runtime)
implementation(libs.androidx.room.ktx)
ksp(libs.androidx.room.compiler)
//crawl
implementation(libs.jsoup)
}
@@ -4,6 +4,7 @@ import com.approagency.drug.data.dto.DarmanModel
import com.approagency.drug.data.dto.DrugListResponse
import com.approagency.drug.data.dto.DrugModels
import retrofit2.http.GET
import retrofit2.http.Headers
import retrofit2.http.Path
import retrofit2.http.Query
@@ -26,4 +27,15 @@ interface DrugApiService {
@GET("drugs/goroh-darmani")
suspend fun getGorohDaroei(): DarmanModel
@GET("Search")
@Headers(
"User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Accept-Language: en-US,en;q=0.5"
)
suspend fun searchDrugs(
@Query("SearchText") searchText: String
): String // Returns raw HTML for the first page
}
@@ -0,0 +1,58 @@
package com.approagency.drug.data.remote
import com.approagency.drug.domain.model.DrugSearchResult
import okio.IOException
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
class DrugHtmlParser {
fun parseSearchResults(html: String): List<DrugSearchResult> {
val document: Document = Jsoup.parse(html)
val results = mutableListOf<DrugSearchResult>()
// Select the table body that contains the drug rows
val rows = document.select("#tbody_DrugList tr")
if (rows.isEmpty()) {
// Handle case where no results are found
return emptyList()
}
for (row in rows) {
try {
// --- Extract Persian Name and Detail Page URL ---
val nameCell = row.selectFirst("td:eq(0)") // First td
val drugLink = nameCell?.selectFirst("a.ahref_Generic")
val persianName = drugLink?.text()?.trim() ?: continue // Skip if no name found
val detailPageRelativeUrl = drugLink?.attr("href") ?: continue
val detailPageUrl = "https://www.darooyab.ir$detailPageRelativeUrl"
// --- Extract Generic ID from URL ---
// URL format: /G-2556/Casanthranol or /G-2556/
val genericIdRegex = "/G-(\\d+)/?".toRegex()
val genericId = genericIdRegex.find(detailPageRelativeUrl)?.groupValues?.get(1) ?: ""
// --- Extract English Name ---
// The last cell contains the English name link
val lastCell = row.select("td").last()
val englishLink = lastCell?.selectFirst("a.ahref_Generic")
val englishName = englishLink?.text()?.trim()
val drugResult = DrugSearchResult(
genericId = genericId,
persianName = persianName,
englishName = englishName,
detailPageUrl = detailPageUrl
)
results.add(drugResult)
} catch (e: Exception) {
// Log error for a specific row but continue with others
println("Error parsing row: ${e.message}")
}
}
return results
}
}
@@ -0,0 +1,8 @@
package com.approagency.drug.domain.model
data class DrugSearchResult(
val genericId: String, // e.g., "2556" from "/G-2556/Casanthranol"
val persianName: String,
val englishName: String? = null, // "Casanthranol", might be null for some entries
val detailPageUrl: String // e.g., "/G-2556/Casanthranol" or "https://www.darooyab.ir/G-2556/Casanthranol"
)
+2 -3
View File
@@ -20,8 +20,9 @@ lifecycleViewmodelKtx = "2.9.4"
room = "2.6.1"
navigationCompose = "2.8.5"
material3 = "1.4.0"
jsoup = "1.18.3"
[libraries]
jsoup = { module = "org.jsoup:jsoup", version.ref = "jsoup" }
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
@@ -51,8 +52,6 @@ location-services = { group = "com.google.android.gms", name = "play-services-lo
androidx-lifecycle-viewmodel-ktx = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "lifecycleViewmodelKtx" }
androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "navigationCompose" }
androidx-material3 = { group = "androidx.compose.material3", name = "material3", version.ref = "material3" }
androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" }
androidx-room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" }
androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" }