Szükséges modulok, beállítások

In [1]:
import urllib.request, time, pandas as pd, random, datetime, os, re
import xmltodict, json
from tqdm import tqdm_notebook
from bs4 import BeautifulSoup
from IPython.display import clear_output

# Function to remove microseconds from timedelta objects.
def chop_microseconds(delta):
    return delta - datetime.timedelta(microseconds=delta.microseconds)

# Set user agent header.
hdr = { 'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; Win64; x64)' }

JSTOR: A szociológia témájú cikkek számának legyűjtése évenként

Tesztelés

In [113]:
# Testing.
url = "https://www.jstor.org/dfr/results?searchType=facetSearch&sd=1960&ed=1961&disc_sociology-discipline_facet=c29jaW9sb2d5LWRpc2NpcGxpbmU%3D&acc=dfr&acc=dfr&acc=dfr"

req = urllib.request.Request(url, headers=hdr)
response = urllib.request.urlopen(req)
d = response.read()
soup = BeautifulSoup(d, "lxml")
In [115]:
# Érték kinyerése.
[item['data-result-count'] for item in soup.find_all('h2', attrs={'data-result-count' : True})][0]
Out[115]:
'8740'

Automatizált lekérések

In [6]:
# Initialize empty DataFrame.
data = pd.DataFrame(columns = ['start', 'end', 'topic', 'keyword', 'results'])
data
Out[6]:
start end topic keyword results
In [7]:
def jstor_scraper(from_year=1886, to_year=2019, min_sleep=2, max_sleep=10):
    # Comment: to_year is not included.
    # Set start time.
    start_time = time.time()
    results = 0
    
    # Generate list of years.
    years = list(range(from_year, to_year, 1))
    
    cnt = 0
    for i in years:
        cnt += 1
        url = "https://www.jstor.org/dfr/results?searchType=facetSearch&sd="+str(i)+"%2F01%2F01&ed="+str(i)+"%2F12%2F31&disc_sociology-discipline_facet=c29jaW9sb2d5LWRpc2NpcGxpbmU%3D&acc=dfr&acc=dfr&acc=dfr"
        req = urllib.request.Request(url, headers=hdr)
        response = urllib.request.urlopen(req)
        d = response.read()
        soup = BeautifulSoup(d, "lxml")

        # Extract item.
        l = [item['data-result-count'] for item in soup.find_all('h2', attrs={'data-result-count' : True})]
        if len(l) == 0: l = [0]

        # Add stuff to DataFrame.
        data.at[cnt, 'results'] = int(l[0])
        data.at[cnt, 'start'] = str(i)+'-01-01'
        data.at[cnt, 'end'] = str(i)+'-12-31'

        # Sleep a random amount of time (between 1 and 10 secs).
        rnd = random.randint(min_sleep,max_sleep)
        clear_output()
        print('Sleeping.........: '+str(rnd)+" secs")
        time.sleep(rnd)
        results += int(l[0])

        # Give feedback.
        print('Year:              '+str(i))
        print('Number of results: '+str(l[0]))
        print('Elapsed time:      '+str(chop_microseconds(datetime.timedelta(seconds=time.time() - start_time))))
        print('Progress:          '+str(cnt)+"/"+str(len(years)))
        print('Number of results: '+str(results))
        if cnt==len(years): print("Done!")
    data.head()
In [8]:
jstor_scraper(from_year=1886, to_year=2019, min_sleep=2, max_sleep=6)
Sleeping.........: 3 secs
Year:              2018
Number of results: 10595
Elapsed time:      0:13:48
Progress:          133/133
Number of results: 670321
Done!
In [9]:
data.head()
Out[9]:
start end topic keyword results
1 1886-01-01 188612-31 NaN NaN 1
2 1887-01-01 188712-31 NaN NaN 0
3 1888-01-01 188812-31 NaN NaN 0
4 1889-01-01 188912-31 NaN NaN 0
5 1890-01-01 189012-31 NaN NaN 39
In [10]:
data.to_excel("../data/data_sociology_1920-2019_v01.xlsx")

Data For Research fájlok feldolgozása

Ki kell szűrni a duplumokat és a 2019-es cikkeket az adatok közül, mert az adatfájlok kikérésénél a 2019-es cikkek is lejöttek.

In [87]:
# Feldolgozandó mappák listája.
basepath = os.path.join('C:/', 'Work')
folders_list = os.listdir(os.path.join(basepath))

# Az adatok egy olyan listába kerülnek, aminek az elemei dictionary-k.
data = []

# A duplumok szűréséhez két lista. Ha benne van a fájlnév, akkor nem dolgozzuk fel.
distinct_ids = []
duplicate_files = []

# Hibakezeléshez egy lista a mappa és fájlnevekkel, és a hiba pontos leírásával.
errors_list = []


for folder in tqdm_notebook(folders_list, desc="Mappák", leave=True):
    keyword = folder.split('-')[1]
    keyword = re.sub('\d', '', keyword)
    keyword = keyword.replace('_', ' ').rstrip()
    
    # Kategória kezelése.
    if keyword in ["automatic summarization", "text classification", "text clustering", "text mining", "topic model", "topic segmentation", "word embedding", "sentiment analysis"]:
        keyword = 'methods'
    elif keyword in ["text analysis", "quantitative text analysis", "qualitative text analysis"]:
        keyword = 'text analysis'
        
    files_list = os.listdir(os.path.join(basepath, folder, 'metadata'))
    for file in tqdm_notebook(files_list, desc=folder, leave=False):        
        # Kihagyjuk azokat a cikkeket, amik egyszer már voltak.
        if file not in distinct_ids: 
            distinct_ids.append(file)
            source = open(os.path.join(basepath, folder, 'metadata', file), 'rb')
            xml = xmltodict.parse(source)
            jsondump = json.dumps(xml)
            jsondict = json.loads(jsondump)
            source.close()

            ### Könyveknél (book-chapter).
            try:
                if file.split('-')[0:2] == ['book', 'chapter']:
                    # Publikáció típusa.
                    pub_type = jsondict['book']['collection-meta']['collection-id']['#text']

                    # Publikáció éve.
                    pub_year = jsondict['book']['book-meta']['pub-date']['year']

                    # Publikáció hónapja.
                    pub_month = jsondict['book']['book-meta']['pub-date']['month']

                    # JSTOR URL lementése.
                    jstor_uri = jsondict['book']['book-meta']['self-uri']['@xlink:href']

                    # Nyelv: nem biztos, hogy mindig a nyelvet szedi le innen.
                    pub_lang = jsondict['book']['book-meta']['custom-meta-group']['custom-meta']['meta-value']

                ### Cikkekre (journal-article).
                elif file.split('-')[0:2] == ['journal', 'article']:
                    pub_type = jsondict['article']['@article-type']

                    # Dátumok: ha több dátum is szerepel, akkor az elsőt vesszük ki.
                    if type(jsondict['article']['front']['article-meta']['pub-date']) == list:
                        pub_year = jsondict['article']['front']['article-meta']['pub-date'][0]['year']
                        try: pub_month = jsondict['article']['front']['article-meta']['pub-date'][0]['month']
                        except KeyError: pub_month = '1'
                    else:
                        pub_year = jsondict['article']['front']['article-meta']['pub-date']['year']
                        try: pub_month = jsondict['article']['front']['article-meta']['pub-date']['month']
                        except KeyError: pub_month = '1'

                    # JSTOR URL lementése.
                    try: jstor_uri = jsondict['article']['front']['article-meta']['self-uri']['@xlink:href']
                    except KeyError: jstor_uri = ''

                    # Nyelv: nem biztos, hogy mindig a nyelvet szedi le innen.
                    pub_lang = jsondict['article']['front']['article-meta']['custom-meta-group']['custom-meta']['meta-value']

                # Mentés.
                data.append({
                    'filename': file,
                    'keyword': keyword,
                    'pub_type': pub_type,
                    'pub_year': pub_year,
                    'pub_month': pub_month,
                    'jstor_uri': jstor_uri,
                    'pub_lang': pub_lang
                })
            # Hibakezelés.
            except Exception as e:
                errors_list.append([folder, file, e])
        
        else: duplicate_files.append(file)

In [88]:
len(data)
Out[88]:
208673
In [89]:
len(errors_list)
Out[89]:
0
In [90]:
len(duplicate_files)
Out[90]:
157917
In [91]:
# Mentés JSON-ban.
with open('data/data_v01.json', 'w') as outfile:
    json.dump(data, outfile)
In [99]:
# Mentés CSV-ben.
data_frame = pd.DataFrame(data)
data_frame.head()
Out[99]:
filename jstor_uri keyword pub_lang pub_month pub_type pub_year
0 book-chapter-10.2307_j.ctt1hd18zq.6.xml https://www.jstor.org/stable/j.ctt1hd18zq methods eng 11 books 2016
1 book-chapter-10.2307_j.ctt7s4z8.13.xml https://www.jstor.org/stable/j.ctt7s4z8 methods eng 09 books 2009
2 book-chapter-10.2307_j.ctt9qff7k.12.xml https://www.jstor.org/stable/j.ctt9qff7k methods eng 10 books 2014
3 book-chapter-10.2307_j.ctv3t5qjk.23.xml https://www.jstor.org/stable/j.ctv3t5qjk methods eng 12 books 2017
4 book-chapter-10.2307_j.ctv6gqs2k.13.xml https://www.jstor.org/stable/j.ctv6gqs2k methods eng 04 books 2006
In [93]:
data_frame.to_csv('data/data_v01.csv')

Folyóiratok számának vizsgálata

In [24]:
# Feldolgozandó mappák listája.
basepath = os.path.join('C:/', 'Work', 'all')
folders_list = os.listdir(os.path.join(basepath))

# Az adatok egy olyan dictionarybe kerülnek, aminek az elemei dictionary-k.
data_jour = {}

# A duplumok szűréséhez egy lista. Ha benne van a fájlnév, akkor nem dolgozzuk fel.
distinct_jour_ids = []

# Hibakezeléshez egy lista a mappa és fájlnevekkel, és a hiba pontos leírásával.
errors_list = []

for folder in tqdm_notebook(folders_list, desc="Mappák", leave=True):
    files_list = os.listdir(os.path.join(basepath, folder, 'metadata'))
    for file in tqdm_notebook(files_list, desc=folder, leave=False):
        try:
            source = open(os.path.join(basepath, folder, 'metadata', file), 'rb')
            xml = xmltodict.parse(source)
            jsondump = json.dumps(xml)
            jsondict = json.loads(jsondump)
            source.close()

            # Folyóirat azonosító
            if type(jsondict['article']['front']['journal-meta']['journal-id']) == list:
                journal_id = jsondict['article']['front']['journal-meta']['journal-id'][0]['#text']
            else:
                journal_id = jsondict['article']['front']['journal-meta']['journal-id']['#text']

            # Dátumok: ha több dátum is szerepel, akkor az elsőt vesszük ki.
            if type(jsondict['article']['front']['article-meta']['pub-date']) == list:
                pub_year = jsondict['article']['front']['article-meta']['pub-date'][0]['year']
            else:
                pub_year = jsondict['article']['front']['article-meta']['pub-date']['year']

            # Kihagyjuk azokat a folyóiratokat, amik egyszer már voltak ebben az évben.
            if pub_year in data_jour:
                if journal_id not in data_jour[pub_year]:
                    data_jour[pub_year].append(journal_id)
            else:
                data_jour[pub_year] = [journal_id]

        # Hibakezelés.
        except Exception as e:
            errors_list.append([folder, file, e])

In [ ]:
data_jour
In [26]:
# Megjegyzés: 16 eset nincs kezelve, de ezek nem adnak hozzá új folyóiratot.
len(errors_list)
Out[26]:
16
In [28]:
# Átalakítás.
data_jour_num = {}
for year in data_jour:
    data_jour_num[year] = len(data_jour[year])
In [43]:
# Mentés JSON-ban.
with open('data/data_journals_v01.json', 'w') as outfile:
    json.dump(data_jour_num, outfile)