I made this python program to find the 64 most common elements of a list stored in a text file. Since this works using binomial names of trees I decided to use the number of mentions in PubMed Central as a metric of popularity. I am just a beginner and somewhat self-taught so I'd like to know if there are any ways of either optimizing this code or improving readability and whether it follows webscraping best practices. The output will be used to seed Facebook polls inside a botany group. Currently the input file has 81825 rows and can be found in this GitHub repository: https://github.com/ascyphermoonshot/larch-madness
import os
import random
import requests
import bs4
import re
from progress.bar import Bar
os.chdir(r"C:\Users\HP\Desktop\larch_madness") #or whatever your filepath is
trees=open('tree_list.txt',mode='r')
trees.seek(0)
treelist=trees.read().splitlines()
treelist=[tree.replace(" ","+").lower() for tree in treelist]
trees.close()
random.shuffle(treelist)
testlist=treelist
baseurl="https://www.ncbi.nlm.nih.gov/pmc/?term=%22{}%22"
finalists=[]
class Tree:
def __init__(self,binomial,popularity):
self.binomial=binomial.replace("+"," ").capitalize()
self.popularity=popularity
def __str__(self):
return self.binomial
def popsearch(baseurl,tree):
searchurl=baseurl.format(tree)
try:
sresult=requests.get(searchurl,timeout=10)
except:
try:
sresult=requests.get(searchurl,timeout=10)
except:
try:
sresult=requests.get(searchurl,timeout=10)
except:
#print("timeout")
return None
soup=bs4.BeautifulSoup(sresult.text,"lxml")
def noresults(soup):
stext=str(soup)
return "No items found." in stext
if not noresults(soup):
try:
resfound=str(soup.find('a', {'title' : 'Total Results'}).text)
#print(resfound)
num=re.search(r"(?<=\()\d+(?=\))",resfound)
num=num.group(0)
#print(num)
return(int(num))
except:
#print ("not found")
return None
else:
#print("no results")
return None
def avoid_riots(finalists):
favs=['Sequoiadendron giganteum','Rhizophora mangle','Ginkgo biloba','Hura crepitans','Taxus baccata','Sequoia sempervivens','Pinus longaeva','Ceiba petandra','Hippomane mancinella','Dracaena cinnabari','Juniperus virginiana','Dendrocnide moroides','Artocarpus heterophyllus','Litchi chinensis','Angiopteris evecta','Pyrus calleryana']
diff=list(set(finalists[0:-15]) - set(favs))
if len(diff)<0:
for x in range(len(diff)):
try:
finalists.pop()
except:
pass
finalists.extend(favs)
finalists=set(finalists)
return list(finalists)
if __name__ == '__main__':
bar = Bar('Scraping', max=len(testlist),suffix='%(percent)d%%')
for tree in testlist:
#print(tree.replace("+"," ").capitalize())
popularity=popsearch(baseurl,tree)
if popularity!=None:
finalists.append(Tree(tree,popularity))
#print("found")
bar.next()
bar.finish()
print("\n"*3)
finalists.sort(key=lambda x: x.popularity, reverse=True)
print(len(finalists))
finalists=finalists[0:64]
tfinalists=[x.binomial for x in finalists]
tfinalists=avoid_riots(tfinalists)
random.shuffle(tfinalists)
for tree in tfinalists:
print(tree)
with open('final tree list.txt', 'w') as f:
f.writelines("%s\n" % l for l in tfinalists)