htmlParser.py 3.6 KB
Newer Older
H
hjdhnx 已提交
1 2 3 4 5 6 7 8
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# File  : htmlParser.py
# Author: DaShenHan&道长-----先苦后甜,任凭晚风拂柳颜------
# Date  : 2022/8/25

from pyquery import PyQuery as pq
from urllib.parse import urljoin
H
hjdhnx 已提交
9
import re
H
hjdhnx 已提交
10 11 12 13 14

class jsoup:
    def __init__(self,MY_URL=''):
        self.MY_URL = MY_URL

H
hjdhnx 已提交
15 16 17 18 19
    def test(self, text, string):
        searchObj = re.search(rf'{text}', string, re.M | re.I)
        test_ret = True if searchObj else False
        return test_ret

H
hjdhnx 已提交
20
    def pdfh(self,html,parse,pd=False):
H
hjdhnx 已提交
21 22
        if not parse:
            return ''
H
hjdhnx 已提交
23 24 25
        doc = pq(html)
        option = None
        if parse.find('&&') > -1:
H
hjdhnx 已提交
26 27 28 29 30 31
            option = parse.split('&&')[-1]
            parse = parse.split('&&')[:-1]  # 如果只有一个&& 取的就直接是0
            if len(parse) > 1:  # 如果不大于1可能就是option操作,不需要拼eq
                parse = ' '.join([i if self.test(':eq|:lt|:gt',i) else f'{i}:eq(0)' for i in parse])
            else:
                parse = parse[0] if self.test(':eq|:lt|:gt',parse[0]) else f'{parse[0]}:eq(0)'
H
hjdhnx 已提交
32 33

        if option:
H
hjdhnx 已提交
34
            # print(f'parse:{parse}=>(option:{option})')
H
hjdhnx 已提交
35
            ret = doc(parse)
H
hjdhnx 已提交
36
            # FIXME 解析出来有多个的情况应该自动取第一个
H
hjdhnx 已提交
37 38 39 40 41 42
            if option == 'Text':
                ret = ret.text()
            elif option == 'Html':
                ret = ret.html()
            else:
                ret = ret.attr(option)
H
hjdhnx 已提交
43
                if pd and option in ['url','src','href','data-original','data-src']:
H
hjdhnx 已提交
44 45
                    ret = urljoin(self.MY_URL,ret)
        else:
H
hjdhnx 已提交
46 47 48 49 50 51 52
            # ret = doc(parse+':first')
            ret = doc(parse) # 由于是生成器,直接转str就能拿到第一条数据,不需要next
            # ret = ret.next()  # 取第一条数据
            # ret = doc(parse) # 下面注释的写法不对的
            # ret = ret.find(':first')
            # ret = ret.children(':first')
            ret = str(ret)
H
hjdhnx 已提交
53 54 55
        return ret

    def pdfa(self,html,parse):
H
hjdhnx 已提交
56 57
        if not parse:
            return []
H
hjdhnx 已提交
58 59 60 61 62
        if parse.find('&&') > -1:
            parse = parse.split('&&')  # 带&&的重新拼接
            # print(f"{parse[0]},{self.test(':eq|:lt|:gt', parse[0])}")
            parse = ' '.join([parse[i] if self.test(':eq|:lt|:gt', parse[i]) or i>=len(parse)-1 else f'{parse[i]}:eq(0)' for i in range(len(parse))])
        # print(f'pdfa:{parse}')
H
hjdhnx 已提交
63 64 65 66 67
        doc = pq(html)
        # return [item.html() for item in doc(parse).items()]
        return [str(item) for item in doc(parse).items()]

    def pd(self,html,parse):
H
hjdhnx 已提交
68 69 70
        return self.pdfh(html,parse,True)

    def pq(self,html):
H
hjdhnx 已提交
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
        return pq(html)

if __name__ == '__main__':
    import requests
    from parsel import Selector
    url = 'http://360yy.cn'
    jsp = jsoup(url)
    def pdfa2(html,parse):
        if not parse:
            return []
        if parse.find('&&') > -1:
            parse = parse.split('&&')  # 带&&的重新拼接
            # print(f"{parse[0]},{self.test(':eq|:lt|:gt', parse[0])}")
            # parse = ' '.join([parse[i] if self.test(':eq|:lt|:gt', parse[i]) or i>=len(parse)-1 else f'{parse[i]}:eq(0)' for i in range(len(parse))])
            parse = ' '.join([parse[i] if jsoup().test(':eq|:lt|:gt', parse[i]) or i>=len(parse)-1 else f'{parse[i]}:nth-child(1)' for i in range(len(parse))])
        # print(f'pdfa:{parse}')
        selector = Selector(text=html)
        print(parse)
        items = selector.css(parse)
        return [str(item) for item in items]
    r = requests.get(url)
    html = r.text
    # parsel 不好用啊,很难实现封装pdfa之类的函数
    items = pdfa2(html,'.fed-pops-navbar&&ul.fed-part-rows&&a')
    print(items)