{"id":187212,"date":"2023-03-23T11:24:45","date_gmt":"2023-03-23T15:24:45","guid":{"rendered":"https:\/\/ibkrcampus.com\/?p=187212"},"modified":"2023-03-24T10:34:32","modified_gmt":"2023-03-24T14:34:32","slug":"beautifulsoup-vs-rvest","status":"publish","type":"post","link":"https:\/\/www.interactivebrokers.com\/campus\/ibkr-quant-news\/beautifulsoup-vs-rvest\/","title":{"rendered":"BeautifulSoup vs. Rvest"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">This post will compare Python\u2019s&nbsp;<a href=\"https:\/\/www.crummy.com\/software\/BeautifulSoup\/bs4\/doc\/\">BeautifulSoup<\/a>&nbsp;package to R\u2019s&nbsp;<a href=\"https:\/\/blog.rstudio.com\/2014\/11\/24\/rvest-easy-web-scraping-with-r\/\">rvest<\/a>&nbsp;package for web scraping. We\u2019ll also talk about additional functionality in&nbsp;<strong>rvest<\/strong>&nbsp;(that doesn\u2019t exist in&nbsp;<strong>BeautifulSoup<\/strong>) in comparison to a couple of other Python packages (including&nbsp;<strong>pandas<\/strong>&nbsp;and&nbsp;<strong>RoboBrowser<\/strong>).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-getting-started\"><strong>Getting started<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong><\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.crummy.com\/software\/BeautifulSoup\/bs4\/doc\/\">BeautifulSoup<\/a>&nbsp;and&nbsp;<a href=\"https:\/\/www.rdocumentation.org\/packages\/rvest\/versions\/0.3.1\">rvest<\/a>&nbsp;both involve creating an object that we can use to parse the HTML from a webpage. However, one immediate difference is that BeautifulSoup is just a web parser, so it doesn\u2019t connect to webpages.&nbsp;<strong>rvest<\/strong>, on the other hand, can connect to a webpage and scrape \/ parse its HTML in a single package.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In BeautifulSoup, our initial setup looks like this:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># load packages\nfrom bs4 import BeautifulSoup\nimport requests\n \n# connect to webpage\nresp = requests.get(\"\"https:\/\/www.azlyrics.com\/b\/beatles.html\"\")\n \n# get BeautifulSoup object\nsoup = BeautifulSoup(resp.content)<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">In comparison, here\u2019s what using&nbsp;<strong>rvest<\/strong>&nbsp;is like:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># load rvest package\nlibrary(rvest)\n \n# get HTML object\nhtml_data &lt;- read_html(\"https:\/\/www.azlyrics.com\/b\/beatles.html\")<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Searching for specific HTML tags<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Next, let\u2019s take our parser objects and find all the links on the page.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you\u2019re familiar with&nbsp;<strong>BeautifulSoup<\/strong>, that would look like:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">links = soup.find_all(\"a\")<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">In rvest, however, we use syntax similar to&nbsp;<strong>dplyr<\/strong>&nbsp;and other tidyverse packages by using %&gt;%.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">links &lt;- html_data %>% html_nodes(\"a\")\n \nurls &lt;- links %>% html_attr(\"href\")<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">In&nbsp;<strong>BeautifulSoup<\/strong>, we use the&nbsp;<em>find_all<\/em>&nbsp;method to extract a list of all of a specific tag\u2019s objects from a webpage. Thus, in the links example, we specify we want to get all of the anchor tags (or \u201ca\u201d tags), which create HTML links on the page. If we wanted to scrape other types of tags, such as&nbsp;<em>div<\/em>&nbsp;tags or&nbsp;<em>p<\/em>&nbsp;tags, we just need to switch out \u201ca\u201d with \u201cdiv\u201d, \u201cp\u201d, or whatever tag we want.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># get all div tags\nsoup.find_all(\"div\")\n \n# get all h1 tags\nsoup.find_all(\"h1\")<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">With&nbsp;<strong>rvest<\/strong>, we can get specific tags from HTML using&nbsp;<em>html_nodes<\/em>. Thus, if we wanted to scrape different tags, such as the div tags or h1 tags, we could do this:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># scrape all div tags\nhtml_data %>% html_nodes(\"div\")\n \n# scrape header h1 tags\nhtml_data %>% html_nodes(\"h1\")<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Getting attributes and text from tags<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong><\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In&nbsp;<strong>BeautifulSoup<\/strong>, we get attributes from HTML tags using the&nbsp;<em>get<\/em>&nbsp;method. We can use a&nbsp;<a href=\"https:\/\/theautomatic.net\/tutorial-on-python-list-comprehensions\/\">list comprehension<\/a>&nbsp;to get the&nbsp;<em><a href=\"https:\/\/www.w3schools.com\/tags\/att_a_href.asp\">href<\/a><\/em>&nbsp;attribute of each link (the&nbsp;<em>href<\/em>&nbsp;attribute of a link is its destination URL).<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">urls = [link.get(\"href\") for link in links]<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">To get other attributes, we just need to change our input to the&nbsp;<em>get<\/em>&nbsp;method.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># get the target attribute from each link\n[link.get(\"target\") for link in links]\n \n# get the ID attribute of each div tag\n[div.get(\"id\") for div in soup.find_all(\"div\")]<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Using&nbsp;<strong>rvest<\/strong>, the&nbsp;<em>html_attr<\/em>&nbsp;function can be used to get attributes from tags. So to get the URL of each link object we scrape, we need to specify that we want to get the&nbsp;<em>href<\/em>&nbsp;attribute from each link, similarly to&nbsp;<strong>BeautifulSoup<\/strong>:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">urls &lt;- links %>% html_attr(\"href\")<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Likewise, if we want to scrape the IDs from the div tags, we can do this:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">html_data %>% html_nodes(\"div\") %>% html_attr(\"id\")<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Notice how, like other tidyverse packages, we can chain together multiple operations.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If we want to scrape the text from each of the links, we can use&nbsp;<em>html_text<\/em>:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">links %>% html_text()<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>BeautifulSoup\u2019s<\/strong>&nbsp;way of accomplishing this is by using the&nbsp;<em>text<\/em>&nbsp;method of a tag object:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">[link.text for link in links]<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Scraping HTML tables<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s look at another example for scraping HTML tables.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We can scrape HTML tables using&nbsp;<strong>rvest\u2019s<\/strong>&nbsp;<em>html_table<\/em>&nbsp;method. This method will extract all tables found on the input webpage. The&nbsp;<em>fill = TRUE<\/em>&nbsp;parameter is specifying that we want to fill any rows that have less than the maximum number of columns in a table with NAs. The tables will be stored as a list of data frames.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">city_data &lt;- read_html(\"https:\/\/www.city-data.com\/city\/Florida.html\")\n \ncity_data %>% html_table(fill = TRUE)<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Scraping tables with&nbsp;<strong>BeautifulSoup<\/strong>&nbsp;into a data frame object is a bit different. One way we can scrape tables with Python is to loop through the tr (row) or td (data cell in table) tags. But the closest analogy of&nbsp;<strong>rvest\u2019s<\/strong>&nbsp;functionality here is to use&nbsp;<strong>pandas<\/strong>:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import pandas as pd\n \npd.read_html(\"https:\/\/www.city-data.com\/city\/Florida.html\")<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Like using&nbsp;<em>html_table<\/em>, this will return a list of data frames corresponding to the tables found on the webpage.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Browser simulation with rvest<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">An additional feature of&nbsp;<strong>rvest<\/strong>&nbsp;is that it can perform browser simulation.&nbsp;<strong>BeautifulSoup<\/strong>&nbsp;cannot do this; however, Python offers several alternatives including&nbsp;<strong>requests_html<\/strong>&nbsp;and&nbsp;<strong>RoboBrowser<\/strong>&nbsp;(each discussed&nbsp;<a href=\"https:\/\/theautomatic.net\/2019\/06\/22\/web-browsing-and-parsing-with-robobrowser-and-requests_html\/\">here<\/a>).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">With&nbsp;<strong>rvest<\/strong>, we can start a browser session using the&nbsp;<em>html_session<\/em>&nbsp;function:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">site = \"https:\/\/www.azlyrics.com\/b\/beatles.html\"\n \nsession &lt;- html_session(site)<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">With our session object, we can navigate to different links on the page, just like a real web browser. There\u2019s a couple ways of doing this. One is to input the index of the link we want to go to. For example, to navigate to the third link of the page, we would write the below code:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">session %>% follow_link(3)<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Here\u2019s a couple more examples:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># navigate to the 5th link on the page\nsession %>% follow_link(5)\n \n# navigate to the 10th link on the page\nsession %>% follow_link(10)<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You can also simulate clicking on links based off text. For example, the below code will navigate to the first link containing the text \u201cSun\u201d. The input is case sensitive.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">session %>% follow_link(\"Sun\")<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You can use the session object to navigate directly to other webpages using the&nbsp;<em>jump_to<\/em>&nbsp;function.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">session %>% jump_to(\"https:\/\/www.azlyrics.com\/a.html\")<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If we use the&nbsp;<strong>RoboBrowser<\/strong>&nbsp;package in Python to somewhat replicate the R code above, we could write this:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">from robobrowser import RoboBrowser\n \n# create a RoboBrowser object\nbrowser = RoboBrowser(history = True)\n  \n# navigate to webpage\nbrowser.open(\"https:\/\/www.azlyrics.com\/b\/beatles.html\")\n \n# get links\nlinks = browser.get_links()\n \n# follow link\nbrowser.follow_link(links[5])\n \n# follow different link\nbrowser.follow_link(links[10])<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The&nbsp;<em>open<\/em>&nbsp;method used above is analogous to&nbsp;<strong>rvest\u2019s<\/strong>&nbsp;<em>jump_to<\/em>&nbsp;function. The&nbsp;<em>follow_link<\/em>&nbsp;method in&nbsp;<strong>RoboBrowser<\/strong>&nbsp;serves a similar purpose to the function of the same name in&nbsp;<strong>rvest<\/strong>, but behaves a little differently. This method takes a&nbsp;<em>link object<\/em>&nbsp;as input, rather than the index of a link, or text within a link that you\u2019re searching for. Thus, we can use the&nbsp;<em>links<\/em>&nbsp;object above to specify a link that we want to \u201cfollow\u201d or click. If we want to click on a link based off text like we did in the&nbsp;<strong>rvest<\/strong>&nbsp;example above, we could write the below code.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># filter the list of links to only links containing \"Sun\" in their text\nsun_links = filter(lambda link: \"Sun\" in link.text, links)\n \n# Click on the first link containing the word \"Sun\"\nbrowser.follow_link(next(sun_links))<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">To learn more about browser simulation in Python,&nbsp;<a href=\"https:\/\/theautomatic.net\/2019\/06\/22\/web-browsing-and-parsing-with-robobrowser-and-requests_html\/\">click here<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Originally posted on <a href=\"https:\/\/theautomatic.net\/2019\/07\/23\/beautifulsoup-vs-rvest\/\">TheAutomatic.net<\/a> blog.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This post will compare Python\u2019s BeautifulSoup package to R\u2019s rvest package for web scraping.<\/p>\n","protected":false},"author":388,"featured_media":182355,"comment_status":"closed","ping_status":"open","sticky":true,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":"","jetpack_post_was_ever_published":false},"categories":[339,343,349,338,350,341,351,352,344,2197,342],"tags":[14986,806,2535,1224,14988,14987,1045,14989],"contributors-categories":[13695],"class_list":["post-187212","post","type-post","status-publish","format-standard","has-post-thumbnail","category-data-science","category-programing-languages","category-python-development","category-ibkr-quant-news","category-quant-asia-pacific","category-quant-development","category-quant-europe","category-quant-north-america","category-quant-regions","category-quant-south-america","category-r-development","tag-beautifulsoup","tag-data-science","tag-dplyr","tag-pandas","tag-robobrowser","tag-rvest","tag-tidyverse","tag-web-scraping","contributors-categories-theautomatic-net"],"pp_statuses_selecting_workflow":false,"pp_workflow_action":"current","pp_status_selection":"publish","acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.9 (Yoast SEO v28.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>BeautifulSoup vs. Rvest | IBKR Quant<\/title>\n<meta name=\"description\" content=\"This post will compare Python\u2019s BeautifulSoup package to R\u2019s rvest package for web scraping.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.interactivebrokers.com\/campus\/wp-json\/wp\/v2\/posts\/187212\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"BeautifulSoup vs. Rvest | IBKR Campus US\" \/>\n<meta property=\"og:description\" content=\"This post will compare Python\u2019s BeautifulSoup package to R\u2019s rvest package for web scraping.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.interactivebrokers.com\/campus\/ibkr-quant-news\/beautifulsoup-vs-rvest\/\" \/>\n<meta property=\"og:site_name\" content=\"IBKR Campus US\" \/>\n<meta property=\"article:published_time\" content=\"2023-03-23T15:24:45+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-03-24T14:34:32+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.interactivebrokers.com\/campus\/wp-content\/uploads\/sites\/2\/2023\/02\/blue-abstract-server.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1000\" \/>\n\t<meta property=\"og:image:height\" content=\"563\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Andrew Treadway\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Andrew Treadway\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\n\t    \"@context\": \"https:\\\/\\\/schema.org\",\n\t    \"@graph\": [\n\t        {\n\t            \"@type\": \"NewsArticle\",\n\t            \"@id\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/ibkr-quant-news\\\/beautifulsoup-vs-rvest\\\/#article\",\n\t            \"isPartOf\": {\n\t                \"@id\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/ibkr-quant-news\\\/beautifulsoup-vs-rvest\\\/\"\n\t            },\n\t            \"author\": {\n\t                \"name\": \"Andrew Treadway\",\n\t                \"@id\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/#\\\/schema\\\/person\\\/d4018570a16fb867f1c08412fc9c64bc\"\n\t            },\n\t            \"headline\": \"BeautifulSoup vs. Rvest\",\n\t            \"datePublished\": \"2023-03-23T15:24:45+00:00\",\n\t            \"dateModified\": \"2023-03-24T14:34:32+00:00\",\n\t            \"mainEntityOfPage\": {\n\t                \"@id\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/ibkr-quant-news\\\/beautifulsoup-vs-rvest\\\/\"\n\t            },\n\t            \"wordCount\": 974,\n\t            \"publisher\": {\n\t                \"@id\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/#organization\"\n\t            },\n\t            \"image\": {\n\t                \"@id\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/ibkr-quant-news\\\/beautifulsoup-vs-rvest\\\/#primaryimage\"\n\t            },\n\t            \"thumbnailUrl\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2023\\\/02\\\/blue-abstract-server.jpg\",\n\t            \"keywords\": [\n\t                \"BeautifulSoup\",\n\t                \"Data Science\",\n\t                \"dplyr\",\n\t                \"Pandas\",\n\t                \"RoboBrowser\",\n\t                \"rvest\",\n\t                \"tidyverse\",\n\t                \"Web Scraping\"\n\t            ],\n\t            \"articleSection\": [\n\t                \"Data Science\",\n\t                \"Programming Languages\",\n\t                \"Python Development\",\n\t                \"Quant\",\n\t                \"Quant Asia Pacific\",\n\t                \"Quant Development\",\n\t                \"Quant Europe\",\n\t                \"Quant North America\",\n\t                \"Quant Regions\",\n\t                \"Quant South America\",\n\t                \"R Development\"\n\t            ],\n\t            \"inLanguage\": \"en-US\"\n\t        },\n\t        {\n\t            \"@type\": \"WebPage\",\n\t            \"@id\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/ibkr-quant-news\\\/beautifulsoup-vs-rvest\\\/\",\n\t            \"url\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/ibkr-quant-news\\\/beautifulsoup-vs-rvest\\\/\",\n\t            \"name\": \"BeautifulSoup vs. Rvest | IBKR Campus US\",\n\t            \"isPartOf\": {\n\t                \"@id\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/#website\"\n\t            },\n\t            \"primaryImageOfPage\": {\n\t                \"@id\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/ibkr-quant-news\\\/beautifulsoup-vs-rvest\\\/#primaryimage\"\n\t            },\n\t            \"image\": {\n\t                \"@id\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/ibkr-quant-news\\\/beautifulsoup-vs-rvest\\\/#primaryimage\"\n\t            },\n\t            \"thumbnailUrl\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2023\\\/02\\\/blue-abstract-server.jpg\",\n\t            \"datePublished\": \"2023-03-23T15:24:45+00:00\",\n\t            \"dateModified\": \"2023-03-24T14:34:32+00:00\",\n\t            \"description\": \"This post will compare Python\u2019s BeautifulSoup package to R\u2019s rvest package for web scraping.\",\n\t            \"inLanguage\": \"en-US\",\n\t            \"potentialAction\": [\n\t                {\n\t                    \"@type\": \"ReadAction\",\n\t                    \"target\": [\n\t                        \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/ibkr-quant-news\\\/beautifulsoup-vs-rvest\\\/\"\n\t                    ]\n\t                }\n\t            ]\n\t        },\n\t        {\n\t            \"@type\": \"ImageObject\",\n\t            \"inLanguage\": \"en-US\",\n\t            \"@id\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/ibkr-quant-news\\\/beautifulsoup-vs-rvest\\\/#primaryimage\",\n\t            \"url\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2023\\\/02\\\/blue-abstract-server.jpg\",\n\t            \"contentUrl\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2023\\\/02\\\/blue-abstract-server.jpg\",\n\t            \"width\": 1000,\n\t            \"height\": 563,\n\t            \"caption\": \"Autocorrelation and Autocovariance: Calculation, Examples, and More \u2013 Part II\"\n\t        },\n\t        {\n\t            \"@type\": \"WebSite\",\n\t            \"@id\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/#website\",\n\t            \"url\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/\",\n\t            \"name\": \"IBKR Campus US\",\n\t            \"description\": \"Financial Education from Interactive Brokers\",\n\t            \"publisher\": {\n\t                \"@id\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/#organization\"\n\t            },\n\t            \"potentialAction\": [\n\t                {\n\t                    \"@type\": \"SearchAction\",\n\t                    \"target\": {\n\t                        \"@type\": \"EntryPoint\",\n\t                        \"urlTemplate\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/?s={search_term_string}\"\n\t                    },\n\t                    \"query-input\": {\n\t                        \"@type\": \"PropertyValueSpecification\",\n\t                        \"valueRequired\": true,\n\t                        \"valueName\": \"search_term_string\"\n\t                    }\n\t                }\n\t            ],\n\t            \"inLanguage\": \"en-US\"\n\t        },\n\t        {\n\t            \"@type\": \"Organization\",\n\t            \"@id\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/#organization\",\n\t            \"name\": \"Interactive Brokers\",\n\t            \"alternateName\": \"IBKR\",\n\t            \"url\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/\",\n\t            \"logo\": {\n\t                \"@type\": \"ImageObject\",\n\t                \"inLanguage\": \"en-US\",\n\t                \"@id\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/#\\\/schema\\\/logo\\\/image\\\/\",\n\t                \"url\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2024\\\/05\\\/ibkr-campus-logo.jpg\",\n\t                \"contentUrl\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2024\\\/05\\\/ibkr-campus-logo.jpg\",\n\t                \"width\": 669,\n\t                \"height\": 669,\n\t                \"caption\": \"Interactive Brokers\"\n\t            },\n\t            \"image\": {\n\t                \"@id\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/#\\\/schema\\\/logo\\\/image\\\/\"\n\t            },\n\t            \"publishingPrinciples\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/about-ibkr-campus\\\/\",\n\t            \"ethicsPolicy\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/cyber-security-notice\\\/\"\n\t        },\n\t        {\n\t            \"@type\": \"Person\",\n\t            \"@id\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/#\\\/schema\\\/person\\\/d4018570a16fb867f1c08412fc9c64bc\",\n\t            \"name\": \"Andrew Treadway\",\n\t            \"description\": \"Andrew Treadway currently works as a Senior Data Scientist, and has experience doing analytics, software automation, and ETL. He completed a master\u2019s degree in computer science \\\/ machine learning, and an undergraduate degree in pure mathematics. Connect with him on LinkedIn: https:\\\/\\\/www.linkedin.com\\\/in\\\/andrew-treadway-a3b19b103\\\/In addition to TheAutomatic.net blog, he also teaches in-person courses on Python and R through my NYC meetup: more details.\",\n\t            \"sameAs\": [\n\t                \"https:\\\/\\\/theautomatic.net\\\/about-me\\\/\"\n\t            ],\n\t            \"url\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/author\\\/andrewtreadway\\\/\"\n\t        }\n\t    ]\n\t}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"BeautifulSoup vs. Rvest | IBKR Quant","description":"This post will compare Python\u2019s BeautifulSoup package to R\u2019s rvest package for web scraping.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.interactivebrokers.com\/campus\/wp-json\/wp\/v2\/posts\/187212\/","og_locale":"en_US","og_type":"article","og_title":"BeautifulSoup vs. Rvest | IBKR Campus US","og_description":"This post will compare Python\u2019s BeautifulSoup package to R\u2019s rvest package for web scraping.","og_url":"https:\/\/www.interactivebrokers.com\/campus\/ibkr-quant-news\/beautifulsoup-vs-rvest\/","og_site_name":"IBKR Campus US","article_published_time":"2023-03-23T15:24:45+00:00","article_modified_time":"2023-03-24T14:34:32+00:00","og_image":[{"width":1000,"height":563,"url":"https:\/\/www.interactivebrokers.com\/campus\/wp-content\/uploads\/sites\/2\/2023\/02\/blue-abstract-server.jpg","type":"image\/jpeg"}],"author":"Andrew Treadway","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Andrew Treadway","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/www.interactivebrokers.com\/campus\/ibkr-quant-news\/beautifulsoup-vs-rvest\/#article","isPartOf":{"@id":"https:\/\/www.interactivebrokers.com\/campus\/ibkr-quant-news\/beautifulsoup-vs-rvest\/"},"author":{"name":"Andrew Treadway","@id":"https:\/\/ibkrcampus.com\/campus\/#\/schema\/person\/d4018570a16fb867f1c08412fc9c64bc"},"headline":"BeautifulSoup vs. Rvest","datePublished":"2023-03-23T15:24:45+00:00","dateModified":"2023-03-24T14:34:32+00:00","mainEntityOfPage":{"@id":"https:\/\/www.interactivebrokers.com\/campus\/ibkr-quant-news\/beautifulsoup-vs-rvest\/"},"wordCount":974,"publisher":{"@id":"https:\/\/ibkrcampus.com\/campus\/#organization"},"image":{"@id":"https:\/\/www.interactivebrokers.com\/campus\/ibkr-quant-news\/beautifulsoup-vs-rvest\/#primaryimage"},"thumbnailUrl":"https:\/\/www.interactivebrokers.com\/campus\/wp-content\/uploads\/sites\/2\/2023\/02\/blue-abstract-server.jpg","keywords":["BeautifulSoup","Data Science","dplyr","Pandas","RoboBrowser","rvest","tidyverse","Web Scraping"],"articleSection":["Data Science","Programming Languages","Python Development","Quant","Quant Asia Pacific","Quant Development","Quant Europe","Quant North America","Quant Regions","Quant South America","R Development"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.interactivebrokers.com\/campus\/ibkr-quant-news\/beautifulsoup-vs-rvest\/","url":"https:\/\/www.interactivebrokers.com\/campus\/ibkr-quant-news\/beautifulsoup-vs-rvest\/","name":"BeautifulSoup vs. Rvest | IBKR Campus US","isPartOf":{"@id":"https:\/\/ibkrcampus.com\/campus\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.interactivebrokers.com\/campus\/ibkr-quant-news\/beautifulsoup-vs-rvest\/#primaryimage"},"image":{"@id":"https:\/\/www.interactivebrokers.com\/campus\/ibkr-quant-news\/beautifulsoup-vs-rvest\/#primaryimage"},"thumbnailUrl":"https:\/\/www.interactivebrokers.com\/campus\/wp-content\/uploads\/sites\/2\/2023\/02\/blue-abstract-server.jpg","datePublished":"2023-03-23T15:24:45+00:00","dateModified":"2023-03-24T14:34:32+00:00","description":"This post will compare Python\u2019s BeautifulSoup package to R\u2019s rvest package for web scraping.","inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.interactivebrokers.com\/campus\/ibkr-quant-news\/beautifulsoup-vs-rvest\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.interactivebrokers.com\/campus\/ibkr-quant-news\/beautifulsoup-vs-rvest\/#primaryimage","url":"https:\/\/www.interactivebrokers.com\/campus\/wp-content\/uploads\/sites\/2\/2023\/02\/blue-abstract-server.jpg","contentUrl":"https:\/\/www.interactivebrokers.com\/campus\/wp-content\/uploads\/sites\/2\/2023\/02\/blue-abstract-server.jpg","width":1000,"height":563,"caption":"Autocorrelation and Autocovariance: Calculation, Examples, and More \u2013 Part II"},{"@type":"WebSite","@id":"https:\/\/ibkrcampus.com\/campus\/#website","url":"https:\/\/ibkrcampus.com\/campus\/","name":"IBKR Campus US","description":"Financial Education from Interactive Brokers","publisher":{"@id":"https:\/\/ibkrcampus.com\/campus\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/ibkrcampus.com\/campus\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/ibkrcampus.com\/campus\/#organization","name":"Interactive Brokers","alternateName":"IBKR","url":"https:\/\/ibkrcampus.com\/campus\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/ibkrcampus.com\/campus\/#\/schema\/logo\/image\/","url":"https:\/\/www.interactivebrokers.com\/campus\/wp-content\/uploads\/sites\/2\/2024\/05\/ibkr-campus-logo.jpg","contentUrl":"https:\/\/www.interactivebrokers.com\/campus\/wp-content\/uploads\/sites\/2\/2024\/05\/ibkr-campus-logo.jpg","width":669,"height":669,"caption":"Interactive Brokers"},"image":{"@id":"https:\/\/ibkrcampus.com\/campus\/#\/schema\/logo\/image\/"},"publishingPrinciples":"https:\/\/www.interactivebrokers.com\/campus\/about-ibkr-campus\/","ethicsPolicy":"https:\/\/www.interactivebrokers.com\/campus\/cyber-security-notice\/"},{"@type":"Person","@id":"https:\/\/ibkrcampus.com\/campus\/#\/schema\/person\/d4018570a16fb867f1c08412fc9c64bc","name":"Andrew Treadway","description":"Andrew Treadway currently works as a Senior Data Scientist, and has experience doing analytics, software automation, and ETL. He completed a master\u2019s degree in computer science \/ machine learning, and an undergraduate degree in pure mathematics. Connect with him on LinkedIn: https:\/\/www.linkedin.com\/in\/andrew-treadway-a3b19b103\/In addition to TheAutomatic.net blog, he also teaches in-person courses on Python and R through my NYC meetup: more details.","sameAs":["https:\/\/theautomatic.net\/about-me\/"],"url":"https:\/\/www.interactivebrokers.com\/campus\/author\/andrewtreadway\/"}]}},"jetpack_featured_media_url":"https:\/\/www.interactivebrokers.com\/campus\/wp-content\/uploads\/sites\/2\/2023\/02\/blue-abstract-server.jpg","_links":{"self":[{"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/posts\/187212","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/users\/388"}],"replies":[{"embeddable":true,"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/comments?post=187212"}],"version-history":[{"count":0,"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/posts\/187212\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/media\/182355"}],"wp:attachment":[{"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/media?parent=187212"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/categories?post=187212"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/tags?post=187212"},{"taxonomy":"contributors-categories","embeddable":true,"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/contributors-categories?post=187212"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}