http://www.apkmirror.com (예 : http://www.apkmirror.com/apk/google-inc/gmail/gmail-7-3-26-152772569-release-release/gmail-7-3-26-152772569-release-android-apk-download/)의 APK 다운로드 페이지를 구문 분석하려고합니다. package
으로 내가 architecture
으로 "팔", version_code
으로 "17329196"을 구문 분석 할PyParsing에서 Word가 주어진 리터럴과 동일하지 않도록 지정하는 방법은 무엇입니까?
, 그리고 "com.skype.m2"일반적으로 "APK보기 '섹션에는 다음과 같은 구조를 가지고 있습니다. 그러나 때로는 architecture
있는 라인은 아래 그림과 같이 누락되었습니다
을 지금까지, 선택과 Scrapy를 사용
apk_details = response.xpath('//*[@title="APK details"]/following-sibling::*[@class="appspec-value"]//text()').extract()
나는 수의 압축을 풉니 '라인을 포함하는 목록을 봤는데 '위에 표시됩니다. 나는 다음과 같은 테스트를 통과하도록하는 기능 parse_apk_details
를 작성하려고 해요 : 위의 주석으로
import pytest
def test_parse_apk_details_with_architecture():
apk_details = [u'Version: 3.0.38_ww (4030038)',
u'arm ',
u'Package: com.lenovo.anyshare.gps',
u'\n',
u'2,239 downloads ']
version_code, architecture, package = parse_apk_details(apk_details)
assert version_code == 4030038
assert architecture == "arm"
assert package == "com.lenovo.anyshare.gps"
@pytest.mark.skip(reason="This does not work yet, because 'Package:' is interpreted by the parser as the architecture.")
def test_parse_apk_details_without_architecture():
apk_details = [u'Version: 3.0.38_ww (4030038)',
u'Package: com.lenovo.anyshare.gps',
u'\n',
u'2,239 downloads ']
version_code, architecture, package = parse_apk_details(apk_details)
assert version_code == 4030038
assert package == "com.lenovo.anyshare.gps"
if __name__ == "__main__":
pytest.main([__file__])
그러나, 두 번째 테스트가 아직 전달하지 않습니다.
from pyparsing import Word, printables, nums, Optional
def parse_apk_details(apk_details):
apk_details = "\n".join(apk_details) # The newline character is ignored by PyParsing (by default)
version_name = Word(printables) # The version name can consist of all printable, non-whitespace characters
version_code = Word(nums) # The version code is expected to be an integer
architecture = Word(printables)
package = Word(printables)
expression = "Version:" + version_name + "(" + version_code("version_code") + ")" + Optional(architecture("architecture")) + "Package:" + package("package")
result = expression.parseString(apk_details)
return int(result.get("version_code")), result.get("architecture"), result.get("package")
내가 두 번째 테스트를 실행하려고하면 내가 오류는 다음과 같습니다 :입니다 :
ParseException: Expected "Package:" (at char 38), (line:2, col:10)
내가 무슨 일이 일어나고하는 일 "패키지"라는 것을 믿고 여기까지 기능입니다 architecture
으로 '소비'됩니다. 이 문제를 해결하는 한 가지 방법은 라인 architecture = Word(printables)
을 (의사 코드로) architecture = Word(printables) + ~"Package:"
과 같이 "Package :"라는 단어를 제외한 인쇄 가능한 문자로 구성 될 수 있음을 나타내는 것으로 변경하는 것입니다.
특정 단어가 "Package:"
이 아닌 경우에만 architecture
이 구문 분석되도록하려면 어떻게해야합니까? (원래 문제의 대안 scrapy
기반 솔루션에도 관심이 있습니다.)
당신은 setResultsName''의 짧은 컷 양식을 사용할 수 있습니다 - 대신 VERSION_NAME = 워드 (printables)'의 .setResultsName ("버전") ' , 그냥'version_name = Word (printables) ("version")'이라고 써라. – PaulMcG