@@ -172,21 +172,31 @@ fun Document.parserMediaMakers(): List<MediaMakerEntity> {
172172fun Document.parserMediaCharacters (): List <MediaCharacterEntity > {
173173 requireNoError()
174174
175- return select(" #columnInSubjectA > div " ).map {
175+ return select(" #columnInSubjectA .item " ).map {
176176 val entity = MediaCharacterEntity ()
177- entity.id = it.select(" h2 a " ).hrefId()
177+ entity.id = it.select(" a.avatar " ).hrefId()
178178 entity.avatar = it.select(" .avatar img" ).attr(" src" ).optImageUrl()
179- entity.titleCn = it.select(" h2 .tip" ).text()
180- entity.titleNative = it.select(" h2 a" ).firsTextNode()
181- entity.commentCount = it.select(" .rr > .na" ).text()
182- entity.personJob = it.select(" .prsn_info > .badge_job" ).text()
183- entity.personSex = it.select(" .prsn_info > .tip" ).text()
179+ entity.titleCn = it.select(" h2 span.tip" ).text()
180+ entity.titleNative = it.select(" h2 a.l" ).text()
181+ entity.commentCount = it.select(" .rr > .primary" ).text()
182+
183+ entity.personJob = it.select(" .badge_job_tip" ).text()
184+ // prsn_info contains the job text inside it. We substring it out to avoid duplication.
185+ val rawSex = it.select(" .prsn_info" ).text()
186+ val jobStr = entity.personJob.orEmpty()
187+ entity.personSex = if (jobStr.isNotEmpty() && rawSex.startsWith(jobStr)) {
188+ rawSex.substringAfter(jobStr).trim()
189+ } else {
190+ rawSex
191+ }
192+
184193 entity.actors = it.select(" .actorBadge" ).map { actor ->
185194 val actorBadge = MediaCharacterEntity .ActorBadge ()
186195 actorBadge.id = actor.select(" a.avatar" ).hrefId()
196+ // Fix: the image is usually located directly inside the a tag
187197 actorBadge.avatar = actor.select(" a.avatar img" ).attr(" src" ).optImageUrl()
188198 actorBadge.name = actor.select(" p a.l" ).text()
189- actorBadge.nameCn = actor.select(" p small" ).text()
199+ actorBadge.nameCn = actor.select(" p small.grey " ).text()
190200 actorBadge
191201 }
192202 entity
@@ -362,19 +372,19 @@ fun Document.parserMediaDetail(): MediaDetailEntity {
362372 }.filterNotNull()
363373
364374 // 角色
365- entity.characters = subjectDetail. select(" #browserItemList > li" ).map { item ->
375+ entity.characters = select(" #browserItemList > li" ).map { item ->
366376 val mediaCharacter = MediaDetailEntity .MediaCharacter ()
367- mediaCharacter.saveCount = item.select(" .userContainer .fade " ).text().parseCount()
368- item.select(" .userContainer a.avatar " ).apply {
377+ mediaCharacter.saveCount = item.select(" .info .primary " ).text().parseCount()
378+ item.select(" a.thumbTip " ).apply {
369379 mediaCharacter.id = hrefId()
370380 mediaCharacter.characterName = attr(" title" )
371- mediaCharacter.avatar = select(" .userImage > span " ).attr(" style" )
381+ mediaCharacter.avatar = select(" .avatarNeue " ).attr(" style" )
372382 .fetchStyleBackgroundUrl().optImageUrl()
373383 }
374- item.select(" .info .tip_j " ).apply {
384+ item.select(" .info" ).apply {
375385 mediaCharacter.jobs = select(" .badge_job_tip" ).map { it.text() }
376- mediaCharacter.characterNameCn = select(" span.tip " ).text()
377- mediaCharacter.persons = select(" a" ).map { person ->
386+ mediaCharacter.characterNameCn = select(" .title a " ).text()
387+ mediaCharacter.persons = select(" .badge_actor a" ).map { person ->
378388 val characterPerson = MediaDetailEntity .MediaCharacterPerson ()
379389 characterPerson.personName = person.text()
380390 characterPerson.personId = person.hrefId()
@@ -402,7 +412,7 @@ fun Document.parserMediaDetail(): MediaDetailEntity {
402412 }
403413
404414 // 关联的条目
405- entity.relativeMedia = subjectDetail. select(" .browserCoverMedium > li" ).map { item ->
415+ entity.relativeMedia = select(" ul .browserCoverMedium:not(#browserItemList) > li" ).map { item ->
406416 val mediaRelative = MediaDetailEntity .MediaRelative ()
407417 mediaRelative.type = item.select(" span.sub" ).text()
408418 item.select(" a.avatar" ).apply {
0 commit comments