1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
U
¡ý°dI_ã@srdZddlmZddlZddlZddlZddlZddlmZm    Z    m
Z
m Z m Z m Z mZmZddddgZd    Zd
Zd Zd Zd ZdZGdd„deƒZGdd„deƒZeƒZGdd„deƒZGdd„deƒZGdd„deƒZGdd„deƒZdd„Z Gdd„de!ƒZ"ddl#m$Z$e e$ƒzddl#m%Z%e e%ƒWne&k
r<YnXzddl#m'Z'e e'ƒWne&k
rlYnXdS)ÚMITé)Ú defaultdictN)ÚCharsetMetaAttributeValueÚContentMetaAttributeValueÚRubyParenthesisStringÚRubyTextStringÚ
StylesheetÚScriptÚTemplateStringÚnonwhitespace_reÚHTMLTreeBuilderÚSAXTreeBuilderÚ TreeBuilderÚTreeBuilderRegistryÚfastZ
permissiveÚstrictÚxmlÚhtmlÚhtml5c@seZdZdZdZdS)ÚXMLParsedAsHTMLWarningzWThe warning issued when an HTML parser is used to parse
    XML that is not XHTML.
    aIt looks like you're parsing an XML document using an HTML parser. If this really is an HTML document (maybe it's XHTML?), you can ignore or filter this warning. If it's XML, you should know that using an XML parser will be more reliable. To parse this document as XML, make sure you have the lxml package installed, and pass the keyword argument `features="xml"` into the BeautifulSoup constructor.N)Ú__name__Ú
__module__Ú __qualname__Ú__doc__ÚMESSAGE©rrúKd:\z\workplace\vscode\pyvenv\venv\Lib\site-packages\bs4/builder/__init__.pyr#src@s(eZdZdZdd„Zdd„Zdd„ZdS)    rzYA way of looking up TreeBuilder subclasses by their name or by desired
    features.
    cCsttƒ|_g|_dS©N)rÚlistÚbuilders_for_featureÚbuilders©ÚselfrrrÚ__init__/s
zTreeBuilderRegistry.__init__cCs0|jD]}|j| d|¡q|j d|¡dS)z¼Register a treebuilder based on its advertised features.
 
        :param treebuilder_class: A subclass of Treebuilder. its .features
           attribute should list its features.
        rN)ÚfeaturesrÚinsertr )r"Ztreebuilder_classÚfeaturerrrÚregister3s
zTreeBuilderRegistry.registercGs¾t|jƒdkrdSt|ƒdkr(|jdSt|ƒ}| ¡d}d}t|ƒdkr”| ¡}|j |g¡}t|ƒdkr@|dkr„|}t|ƒ}q@| t|ƒ¡}q@|dkr dS|D]}||kr¤|Sq¤dS)ajLook up a TreeBuilder subclass with the desired features.
 
        :param features: A list of features to look for. If none are
            provided, the most recently registered TreeBuilder subclass
            will be used.
        :return: A TreeBuilder subclass, or None if there's no
            registered subclass with all the requested features.
        rN)    Úlenr rÚreverseÚpoprÚgetÚsetÚ intersection)r"r$Ú
candidatesZ candidate_setr&Zwe_have_the_featureÚ    candidaterrrÚlookup=s0     
 
ÿ
zTreeBuilderRegistry.lookupN)rrrrr#r'r0rrrrr*s
c@s˜eZdZdZdZgZgZdZdZdZ    e
e ƒZ e ƒZiZeƒZdZeeeefdd„Zdd„Zd    d
„Zd d „Zd d„Zddd„Zdd„Zdd„Zdd„ZdS)rz:Turn a textual document into a Beautiful Soup object tree.z[Unknown tree builder]FNcCsbd|_||jkr|j}||_||jkr,|j}||_||jkrB|j}||_||jkrX|j}||_    dS)aÜConstructor.
 
        :param multi_valued_attributes: If this is set to None, the
         TreeBuilder will not turn any values for attributes like
         'class' into lists. Setting this to a dictionary will
         customize this behavior; look at DEFAULT_CDATA_LIST_ATTRIBUTES
         for an example.
 
         Internally, these are called "CDATA list attributes", but that
         probably doesn't make sense to an end-user, so the argument name
         is `multi_valued_attributes`.
 
        :param preserve_whitespace_tags: A list of tags to treat
         the way <pre> tags are treated in HTML. Tags in this list
         are immune from pretty-printing; their contents will always be
         output as-is.
 
        :param string_containers: A dictionary mapping tag names to
        the classes that should be instantiated to contain the textual
        contents of those tags. The default is to use NavigableString
        for every tag, no matter what the name. You can override the
        default by changing DEFAULT_STRING_CONTAINERS.
 
        :param store_line_numbers: If the parser keeps track of the
         line numbers and positions of the original markup, that
         information will, by default, be stored in each corresponding
         `Tag` object. You can turn this off by passing
         store_line_numbers=False. If the parser you're using doesn't 
         keep track of this information, then setting store_line_numbers=True
         will do nothing.
        N)
ÚsoupÚ USE_DEFAULTÚDEFAULT_CDATA_LIST_ATTRIBUTESÚcdata_list_attributesÚ DEFAULT_PRESERVE_WHITESPACE_TAGSÚpreserve_whitespace_tagsÚTRACKS_LINE_NUMBERSÚstore_line_numbersÚDEFAULT_STRING_CONTAINERSÚstring_containers)r"Zmulti_valued_attributesr6r8r:rrrr#‹s$
 
 
 
zTreeBuilder.__init__cCs
||_dS)zžThe BeautifulSoup object has been initialized and is now
        being associated with the TreeBuilder.
 
        :param soup: A BeautifulSoup object.
        N)r1)r"r1rrrÚinitialize_soup½szTreeBuilder.initialize_soupcCsdS)zDo any work necessary to reset the underlying parser
        for a new document.
 
        By default, this does nothing.
        Nrr!rrrÚresetÅszTreeBuilder.resetcCs|jdkrdS||jkS)aßMight a tag with this name be an empty-element tag?
 
        The final markup may or may not actually present this tag as
        self-closing.
 
        For instance: an HTMLBuilder does not consider a <p> tag to be
        an empty-element tag (it's not in
        HTMLBuilder.empty_element_tags). This means an empty <p> tag
        will be presented as "<p></p>", not "<p/>" or "<p>".
 
        The default implementation has no opinion about which tags are
        empty-element tags, so a tag will be presented as an
        empty-element tag if and only if it has no children.
        "<foo></foo>" will become "<foo/>", and "<foo>bar</foo>" will
        be left alone.
 
        :param tag_name: The name of a markup tag.
        NT)Úempty_element_tags)r"Útag_namerrrÚcan_be_empty_elementÍs
z TreeBuilder.can_be_empty_elementcCs
tƒ‚dS)zùRun some incoming markup through some parsing process,
        populating the `BeautifulSoup` object in self.soup.
 
        This method is not implemented in TreeBuilder; it must be
        implemented in subclasses.
 
        :return: None.
        N©ÚNotImplementedError©r"ÚmarkuprrrÚfeedäs    zTreeBuilder.feedccs|dddfVdS)aRun any preliminary steps necessary to make incoming markup
        acceptable to the parser.
 
        :param markup: Some markup -- probably a bytestring.
        :param user_specified_encoding: The user asked to try this encoding.
        :param document_declared_encoding: The markup itself claims to be
            in this encoding. NOTE: This argument is not used by the
            calling code and can probably be removed.
        :param exclude_encodings: The user asked _not_ to try any of
            these encodings.
 
        :yield: A series of 4-tuples:
         (markup, encoding, declared encoding,
          has undergone character replacement)
 
         Each 4-tuple represents a strategy for converting the
         document to Unicode and parsing it. Each strategy will be tried 
         in turn.
 
         By default, the only strategy is to parse the markup
         as-is. See `LXMLTreeBuilderForXML` and
         `HTMLParserTreeBuilder` for implementations that take into
         account the quirks of particular parsers.
        NFr)r"rCZuser_specified_encodingZdocument_declared_encodingZexclude_encodingsrrrÚprepare_markupïszTreeBuilder.prepare_markupcCs|S)aWrap an HTML fragment to make it look like a document.
 
        Different parsers do this differently. For instance, lxml
        introduces an empty <head> tag, and html5lib
        doesn't. Abstracting this away lets us write simple tests
        which run HTML fragments through the parser and compare the
        results against other HTML fragments.
 
        This method should not be used outside of tests.
 
        :param fragment: A string -- fragment of HTML.
        :return: A string -- a full HTML document.
        r)r"ÚfragmentrrrÚtest_fragment_to_document sz%TreeBuilder.test_fragment_to_documentcCsdS)a2Set up any substitutions that will need to be performed on 
        a `Tag` when it's output as a string.
 
        By default, this does nothing. See `HTMLTreeBuilder` for a
        case where this is used.
 
        :param tag: A `Tag`
        :return: Whether or not a substitution was performed.
        Fr)r"ÚtagrrrÚset_up_substitutionss
z TreeBuilder.set_up_substitutionscCs‚|s|S|jr~|j dg¡}|j | ¡d¡}t| ¡ƒD]B}||ksR|r:||kr:||}t|tƒrpt |¡}n|}|||<q:|S)aáWhen an attribute value is associated with a tag that can
        have multiple values for that attribute, convert the string
        value to a list of strings.
 
        Basically, replaces class="foo bar" with class=["foo", "bar"]
 
        NOTE: This method modifies its input in place.
 
        :param tag_name: The name of a tag.
        :param attrs: A dictionary containing the tag's attributes.
           Any appropriate attribute values will be modified in place.
        Ú*N)    r4r+ÚlowerrÚkeysÚ
isinstanceÚstrr Úfindall)r"r>ÚattrsÚ    universalZ tag_specificÚattrÚvalueÚvaluesrrrÚ$_replace_cdata_list_attribute_values's  ÿ
 
z0TreeBuilder._replace_cdata_list_attribute_values)NNN)rrrrÚNAMEZALTERNATE_NAMESr$Zis_xmlZ    picklabler=rrr3r,r5r9Úobjectr2r7r#r;r<r?rDrErGrIrUrrrrros8ý
2 ÿ
 c@sheZdZdZdd„Zdd„Zdd„Zdd    „Zd
d „Zd d „Z    dd„Z
dd„Z dd„Z dd„Z dd„ZdS)r z©A Beautiful Soup treebuilder that listens for SAX events.
 
    This is not currently used for anything, but it demonstrates
    how a simple TreeBuilder would work.
    cCs
tƒ‚dSrr@rBrrrrDTszSAXTreeBuilder.feedcCsdSrrr!rrrÚcloseWszSAXTreeBuilder.closecCs,tdd„t| ¡ƒDƒƒ}|j ||¡dS)Ncss|]\}}|d|fVqdS)éNr)Ú.0ÚkeyrSrrrÚ    <genexpr>[sz.SAXTreeBuilder.startElement.<locals>.<genexpr>)ÚdictrÚitemsr1Úhandle_starttag)r"ÚnamerPrrrÚ startElementZszSAXTreeBuilder.startElementcCs|j |¡dSr)r1Ú handle_endtag©r"r`rrrÚ
endElement_szSAXTreeBuilder.endElementcCs| ||¡dSr)ra)r"ÚnsTupleÚnodeNamerPrrrÚstartElementNScszSAXTreeBuilder.startElementNScCs| |¡dSr)rd)r"rerfrrrÚ endElementNSgszSAXTreeBuilder.endElementNScCsdSrr)r"ÚprefixZ    nodeValuerrrÚstartPrefixMappinglsz!SAXTreeBuilder.startPrefixMappingcCsdSrr)r"rirrrÚendPrefixMappingpszSAXTreeBuilder.endPrefixMappingcCs|j |¡dSr)r1Ú handle_data)r"ÚcontentrrrÚ
charactersuszSAXTreeBuilder.characterscCsdSrrr!rrrÚ startDocumentxszSAXTreeBuilder.startDocumentcCsdSrrr!rrrÚ endDocument{szSAXTreeBuilder.endDocumentN)rrrrrDrXrardrgrhrjrkrnrorprrrrr Msc$@søeZdZdZedddddddd    d
d d d ddddddddddddgƒZeddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.dd/d0d1d2d3d4d5d6d7d8d9d:d;g#ƒZeee    e
e d<œZ d=d>d?gd@dAgd@dAgdBgdBgdBgdCgdDgd@gdEgdFgdGgdHœ Z ed6dIgƒZdJdK„ZdLS)Mr z]This TreeBuilder knows facts about HTML.
 
    Such as which tags are empty-element tags.
    ÚareaÚbaseÚbrÚcolÚembedÚhrÚimgÚinputÚkeygenÚlinkZmenuitemÚmetaÚparamÚsourceÚtrackÚwbrÚbasefontÚbgsoundÚcommandÚframeÚimageÚisindexZnextidZspacerÚaddressÚarticleÚasideÚ
blockquoteZcanvasÚddÚdivÚdlÚdtÚfieldsetÚ
figcaptionÚfigureÚfooterÚformÚh1Úh2Úh3Úh4Úh5Úh6ÚheaderÚliÚmainÚnavÚnoscriptÚolÚoutputÚpÚpreÚsectionÚtableÚtfootÚulÚvideo)ÚrtÚrpÚstyleÚscriptÚtemplateÚclassZ    accesskeyZdropzoneÚrelÚrevÚheaderszaccept-charsetÚarchiveÚsizesZsandboxÚfor) rJÚarzÚtdÚthr´r’rWrqZiconÚiframerŸÚtextareacCsz|jdkrdS| d¡}| d¡}| d¡}d}|dk    rJ|}t|ƒ|d<n(|dk    rr|dk    rr| ¡dkrrt|ƒ|d<|dk    S)a–Replace the declared encoding in a <meta> tag with a placeholder,
        to be substituted when the tag is output to a string.
 
        An HTML document may come in to Beautiful Soup as one
        encoding, but exit in a different encoding, and the <meta> tag
        needs to be changed to reflect this.
 
        :param tag: A `Tag`
        :return: Whether or not a substitution was performed.
        r{Fz
http-equivrmÚcharsetNz content-type)r`r+rrKr)r"rHZ
http_equivrmr¸Z meta_encodingrrrrIÅs
 
 
 
 
ÿ z$HTMLTreeBuilder.set_up_substitutionsN)rrrrr,r=Zblock_elementsrrrr    r
r9r3r5rIrrrrr sbû Nûò c@sdeZdZdZe dej¡Ze dej¡ZdZ    dZ
e dd„ƒZ e dd    „ƒZ d
d „Zd d „Zdd„ZdS)ÚDetectsXMLParsedAsHTMLaA mixin class for any class (a TreeBuilder, or some class used by a
    TreeBuilder) that's in a position to detect whether an XML
    document is being incorrectly parsed as HTML, and issue an
    appropriate warning.
 
    This requires being able to observe an incoming processing
    instruction that might be an XML declaration, and also able to
    observe tags as they're opened. If you can't do that for a given
    TreeBuilder, there's a less reliable implementation based on
    examining the raw markup.
    z
<[^ +]htmls
<[^ +]htmlz<?xmls<?xmlcCsXt|tƒr|j}|j}n |j}|j}|dk    rT| |¡rT| |dd…¡sT| ¡dSdS)aJPerform a check on some markup to see if it looks like XML
        that's not XHTML. If so, issue a warning.
 
        This is much less reliable than doing the check while parsing,
        but some of the tree builders can't do that.
 
        :return: True if the markup looks like non-XHTML XML, False
        otherwise.
        NiôTF)    rMÚbytesÚ XML_PREFIX_BÚLOOKS_LIKE_HTML_BÚ
XML_PREFIXÚLOOKS_LIKE_HTMLÚ
startswithÚsearchÚ_warn)ÚclsrCriZlooks_like_htmlrrrÚwarn_if_markup_looks_like_xmls
ÿþz4DetectsXMLParsedAsHTML.warn_if_markup_looks_like_xmlcCst tjt¡dS)z/Issue a warning about XML being parsed as HTML.N)ÚwarningsÚwarnrr)rÂrrrrÁsÿzDetectsXMLParsedAsHTML._warncCsd|_d|_dS)z+Call this method before parsing a document.N©Ú_first_processing_instructionÚ    _root_tagr!rrrÚ_initialize_xml_detector%sz/DetectsXMLParsedAsHTML._initialize_xml_detectorcCs"|jdk    s|jdk    rdS||_dS)z‡Call this method when encountering an XML declaration, or a
        "processing instruction" that might be an XML declaration.
        NrÆ)r"Zprocessing_instructionrrrÚ_document_might_be_xml*s
 
ÿz-DetectsXMLParsedAsHTML._document_might_be_xmlcCsB|jdk    rdS||_|dkr>|jdk    r>|j ¡ d¡r>| ¡dS)zÃCall this when you encounter the document's root tag.
 
        This is where we actually check whether an XML document is
        being incorrectly parsed as HTML, and issue the warning.
        Nrzxml )rÈrÇrKr¿rÁrcrrrÚ_root_tag_encountered9s
ÿz,DetectsXMLParsedAsHTML._root_tag_encounteredN)rrrrÚreÚcompileÚIr¾r¼r½r»Ú classmethodrÃrÁrÉrÊrËrrrrr¹ðs 
 
r¹cCsRtjt}|jD]<}t||ƒ}t|tƒrt|||ƒ|j |¡|j     
|¡qdS)z9Copy TreeBuilders from the given module into this module.N) ÚsysÚmodulesrÚ__all__ÚgetattrÚ
issubclassrÚsetattrÚappendÚbuilder_registryr')ÚmoduleZ this_moduler`ÚobjrrrÚregister_treebuilders_fromMs
 
 
 
  rÚcs eZdZdZ‡fdd„Z‡ZS)ÚParserRejectedMarkupzgAn Exception to be raised when the underlying parser simply
    refuses to parse the given markup.
    cs6t|tƒr"|}d|jjt|ƒf}tt|ƒ |¡dS)zzExplain why the parser rejected the given markup, either
        with a textual explanation or another exception.
        z%s: %sN)rMÚ    ExceptionÚ    __class__rrNÚsuperrÛr#)r"Zmessage_or_exceptionÚe©rÝrrr#]s
zParserRejectedMarkup.__init__)rrrrr#Ú __classcell__rrràrrÛYsrÛrY)Ú _htmlparser)Ú    _html5lib)Ú_lxml)(Ú __license__Ú collectionsrÚ    itertoolsrÌrÄrÐZ bs4.elementrrrrrr    r
r rÒZFASTZ
PERMISSIVEZSTRICTÚXMLZHTMLZHTML_5Ú UserWarningrrWrr×rr r r¹rÚrÜrÛÚrârãÚ ImportErrorrärrrrÚ<module>sN ( üC_2q]