我正在尝试获取有关期刊文章的元数据;具体来说,每篇文章属于期刊的哪一部分。我正在使用find_all首先获取带有文章标题的所有标签,然后使用它来解析与文章部分和url信息的标签。
在测试代码时,我将其所有的标题,URL和文章类型打印到终端上,以便可以检查脚本是否获取了正确的数据。 正确的信息是打印(即所有唯一的标题和URL及其文章类型),因此我认为自己走在正确的轨道上。
问题是,当我实际运行下面粘贴的代码时,输出中的行数与问题中的文章数相对应,但是每一行都是该文章最后一篇文章的元数据的重复问题,而不是显示每篇文章的唯一数据。例如,如果一个问题有42篇文章,而不是输出中的42行代表该问题中的另一篇文章,那么我只会获得该问题中最后一篇文章的数据,在输出中重复42次。
我在代码中忽略了什么,以确保输出确实包含这些问题中每篇文章的所有唯一数据?
import requests
from bs4 import BeautifulSoup
import csv
import pandas as pd
import re
from lxml.html import fromstring
import requests
from itertools import cycle
import traceback
def get_proxies():
url = 'https://free-proxy-list.net/'
response = requests.get(url)
parser = fromstring(response.text)
proxies = set()
for i in parser.xpath('//tbody/tr')[:10]:
if i.xpath('.//td[7][contains(text(),"yes")]'):
proxy = ":".join([i.xpath('.//td[1]/text()')[0], i.xpath('.//td[2]/text()')[0]])
proxies.add(proxy)
return proxies
json_data =[]
base_url = 'https://ajph.aphapublications.org'
#Get Health Affairs 2018 issues
ajph2018 = ['https://ajph.aphapublications.org/toc/ajph/108/1',
'https://ajph.aphapublications.org/toc/ajph/108/2',
'https://ajph.aphapublications.org/toc/ajph/108/3',
'https://ajph.aphapublications.org/toc/ajph/108/4',
'https://ajph.aphapublications.org/toc/ajph/108/5',
'https://ajph.aphapublications.org/toc/ajph/108/6',
'https://ajph.aphapublications.org/toc/ajph/108/7',
'https://ajph.aphapublications.org/toc/ajph/108/8',
'https://ajph.aphapublications.org/toc/ajph/108/9',
'https://ajph.aphapublications.org/toc/ajph/108/10',
'https://ajph.aphapublications.org/toc/ajph/108/11',
'https://ajph.aphapublications.org/toc/ajph/108/12',
'https://ajph.aphapublications.org/toc/ajph/108/S1',
'https://ajph.aphapublications.org/toc/ajph/108/S2',
'https://ajph.aphapublications.org/toc/ajph/108/S3',
'https://ajph.aphapublications.org/toc/ajph/108/S4',
'https://ajph.aphapublications.org/toc/ajph/108/S5',
'https://ajph.aphapublications.org/toc/ajph/108/S6',
'https://ajph.aphapublications.org/toc/ajph/108/S7']
for a in ajph2018:
issue=requests.get(a)
soup1=BeautifulSoup(issue.text, 'lxml')
#Get articles data
ajph18_dict={"url":"NaN","articletype":"NaN", "title":"NaN"}
all_titles = soup1.find_all("span", {"class":"hlFld-Title"})
for each in all_titles:
title = each.text.strip()
articletype=each.find_previous("h2", {"class":"tocHeading"}).text.strip()
doi_tag = each.find_previous("a", {"class":"ref nowrap", "href": True})
doi = doi_tag["href"]
url = base_url + doi
if url is not None:
ajph18_dict["url"]=url
if title is not None:
ajph18_dict["title"]=title
if articletype is not None:
ajph18_dict["articletype"]=articletype.text.strip()
json_data.append(ajph18_dict)
df=pd.DataFrame(json_data)
df.to_csv("ajph_type.csv")
print("Saved")
答案 0 :(得分:1)
每次在for循环中都添加相同的字典(ajph18_dict
)时,对该字典所做的任何更改都会反映在列表的每个元素中。最后一个循环会覆盖之前的所有更改,因此您只需从最后一个循环中获取值
您需要将ajph18_dict={"url":"NaN","articletype":"NaN", "title":"NaN"}
行放在for循环中,以便在每个循环中创建一个新对象
例如:
d = {}
l = []
for i in range(3):
d['foo'] = i
l.append(d) # This just appends a reference to the same object every time
l
现在是一个包含3个元素的列表,这些元素都是对同一词典d
的引用。 d
现在看起来像这样{'foo': 2}
,l
现在看起来像这样[{'foo': 2}, {'foo': 2}, {'foo': 2}]
l = []
for i in range(3):
d = {} # "d" is a new object every loop
d['foo'] = i
l.append(d) # every element in "l" is a different object
[{'foo': 0}, {'foo': 1}, {'foo': 2}]