Package: scrapepath
ScrapepathScrapepathis a templated web scraping syntax.Scrapepath is pip installableviapip install scrapepath.RequirementsInstall the required Python dependencies using the provided requirements.txt file, by:pipinstall-rrequirements.txtUsageTo run an example, execute on the command line without arguments:./parserTo use within Python:fromparserimportNodeParsernp=NodeParser(soup_template,soup,live_url)np.hop_template()print(json.dumps(np.result_dict,indent=2,default=str))Wheresoup_templateis aBeautifulSoupof the template file,soupis aBeautifulSoupof the scraped page andlive_urlthe url of the scraped page.TemplatesHTML pages are scraped using HTML templates, consisting of a mixture of the most important tags, and statements.Templates consist of HTML files containing nested tags leading to the scraping element of interest.The parser is based onBeautifulSoup.Example 1: Scraping dataThe following examples are from scraped pagesexamples/example1a.htmland templateexamples/scraped1.html. Run the example using:./parser.py examples/example1a.html examples/scraped1.htmlThis scrapes the target pagescraped1.htmlusing thetemplate example1a.html. The text item "Tea" is scraped from the target page using therecordattribute in the template page. A path to the target text ("Tea") is specified in the template using tags that correspond to the target page. So, to scrape from:<ulclass="my_list"><liclass="my_item">Coffee</li><liclass="my_item"><spanclass="cuppa">Tea</span></li><liclass="my_item">Milk</li></ul>Use template:<ulclass="my_list"><spanclass="cuppa"record="text as favorite"></span></ul>This yields a dictionary containing the scraped data under the key "favorite" as specified in therecordattribute:{"favorite":"Tea"}Thetextstatement within the record attribute corresponds to a function that obtains text from inside the HTML tag, andfavoriteis the key to record the data against. Thetextfunction can be replaced with custom Python functions.Starting from the outer node,<ul>, in the template, the parser looks for the first node in the scraped page that matches the template node in type and attributes. In this case, matching a ul with a ul, and class my_list with class my_list. Then, the same search takes place using the template node children, now confined within the children of the scraped node. So nested template nodes represent paths. The<li>node is not included in the template, as it would point the search to the first element of the list.In this case, nesting the template nodes is needlessly specific. There are no other nodes of class "cuppa", so we can omit the<ul>and<li>items, and the following template will record the same data:<spanclass="cuppa"record="text as favorite"></span>So paths along many nested nodes in the scraped page can be summarized by only a few nodes that define a unique path to the scraped data.Loops:Aforloop scrapes all items in the list. In this simple example, we record only one variable (item_text) per item:Template:<ulclass="my_list"><foritems="items"condition="i < 5"><liclass="my_item"record="text as item_text"></li></for></ul>This results in the output:{"items":[{"item_text":"Coffee"},{"item_text":"Tea"},{"item_text":"Milk"},{"item_text":"Biscuits"},{"item_text":"Chocolate"}]}Here, the parser matches all the children of the<for>template node to the children of the<ul>node in the scraped pagescraped1.html. Run the example using:./parser.py examples/example1b.html examples/scraped1.html. Theconditionnode indicates that only the first 5 items should be recorded, whereiis the loop counter variable.Example 2: for loops on mixed nodesIn the following html, a<for>template loop node needs to enclose two template nodes, one for each tag (div and p) and class (my_item and milk_class):To scrape from:<divclass="my_list"><divclass="my_item">Coffee</div><divclass="my_item"><spanclass="cuppa">Tea</span></div><pclass="milk_class">Milk</p><divclass="my_item">Biscuits</div>Chocolate</div>Use template:<divclass="my_list"><foritems="items"><divclass="my_item"record="text as item_text"></div><pclass="milk_class"record="text as item_text"></p></for></div>However, the<for>template loop node is unable to record the text element "chocolate", as the<for>only looks for proper nodes among the children of the<div class = "my_list">node. To do this, a<forchild>template loop node is needed, along with a<str>template node to record theNavigableStringelement "chocolate":Template:<divclass="my_list"><forchilditems="items_with_string"><divclass="my_item"record="text as item_text"></div><pclass="milk_class"record="text as item_text"></p><strrecord="text as item_text"></div></forchild></div>In this case, the parser looks for the first match to the first template node (the child of the<for>node), and loops over its sibblings, probing with all template nodes (the children of this for node). Run this example usingexamples/example1b.htmlandexamples/scraped1.html.Example 3: Jumping to linked pagesFollow links on pages using the<jump>template node:To scrape from:<ahref="example_linked.html"></a>Use template:<arecord="href as my_link"><jumpon="my_link"><ibody><divclass="message"record="text as msg_from_link"></div></ibody></jump><a>Here, the nodes within the<jump>node act on the linked page.This example is invoked with:./parser.pyexamples/example3a.htmlexamples/scraped3.html