我正在使用一个Web Scraper,如果它与关键字列表匹配,则将返回作业发布的链接和描述。我的问题是,导出的csv只是链接和说明进入一行的一长句。
如何有效地将描述和链接分成两个单独的列?以及如何添加链接的其余部分以便能够单击csv内的链接?还有一种避免在csv中重复条目的方法吗?
这是我的代码:
from selenium import webdriver
import time, re, csv
from bs4 import BeautifulSoup as BS
keywords = ["KI", "AI", "Big Data", "Data", "data", "big data",
"Analytics", "analytics", "digitalisierung", "ML",
"Machine Learning", "Daten", "Datenexperte",
"Datensicherheitsexperte", "Analytikleistungen"]
browser = webdriver.Chrome()
url = "https://ausschreibungen.usp.gv.at/at.gv.bmdw.eproc-p/public"
browser.implicitly_wait(30)
browser.get(url)
innerHTML = browser.execute_script("return
document.body.innerHTML")
soup = BS(browser.page_source, 'html.parser')
# browser.quit()
# print(soup.text)
tenders = soup.find('table', {'id': 'tenderlist'})
tbody = tenders.find('tbody')
browser.quit()
ausschreiben_found = []
for tr in tbody.find_all('tr'):
ausschreiben = tr.find_all('td')
for keyword in keywords:
for word in ausschreiben:
if keyword in str(word):
ausschreiben_found.append(word)
print(ausschreiben_found)
with open("ausschreiben.csv", 'a', encoding='utf-8') as toWrite:
fieldnames = ["Beschreibung", "Links"]
writer = csv.writer(toWrite)
writer.writerows(ausschreiben_found)
# subprocess.call('./Autopilot3.py')
print("Matched Ausschreiben have been collected.")
答案 0 :(得分:2)
由于网站使用Ajax和JavaScript库填充页面上的表,因此获取所需数据的最简单方法是复制Ajax请求。
来自服务器的JSON数据具有以下结构:
{
"value": {
"draw": "-1",
"recordsTotal": 1476,
"recordsFiltered": 1476,
"data": [{
"DT_RowClass": "even",
"0": "<a href=\"/at.gv.bmdw.eproc-p/public/de_AT/tenderlist?action=view&object=41a809d9-0b61-4991-86b8-74dc07973af3-15ed14df-d91c-4905-94fd-e1d7935eaef1\">Planung Freiland/Brücke</a>",
"1": "Autobahnen- und Schnellstraßen-Finanzierungs-Aktiengesellschaft",
"2": "08.04.2019",
"3": null
}, {
"DT_RowClass": "odd",
"0": "<a href=\"/at.gv.bmdw.eproc-p/public/de_AT/tenderlist?action=view&object=86dd87bd-7426-40c5-946b-62b2af638aab-7a54478b-9e89-4d47-bdf8-dc8b867c57b8\">Lieferung von Erdgas 2020 - 2022</a>",
"1": "Republik Österreich (Bund), Bundesbeschaffung GmbH sowie alle weiteren Auftraggeber gemäß der den Ausschreibungsunterlagen beiliegenden Drittkundenliste, im Vergabeverfahren alle vertreten durch die Bundesbeschaffung GmbH",
"2": "08.04.2019",
"3": "07.05.2019"
}]
}
}
以下内容使用requests
模块从服务器获取JSON,并使用最新的HTML解析器从链接中提取文本。您可以出于相同目的自由使用BeautifulSoup。
import requests
from html.parser import HTMLParser
class TinyTextExtractor(HTMLParser):
def parse(self, html):
self.text = ''
self.feed(html)
return self.text
def handle_data(self, data):
self.text += data
def get_ausschreibungen(start=0, length=25):
url = 'https://ausschreibungen.usp.gv.at/at.gv.bmdw.eproc-p/ajax/dataTablesTenderList'
resp = requests.get(url, {
'start': start,
'length': length
})
parser = TinyTextExtractor()
for row in resp.json()['value']['data']:
yield {
'Bezeichnung': parser.parse(row['0']),
'Organisation': row['1'],
'Veröffentlicht': row['2'],
'Frist': row['3'],
}
用法:
for item in get_ausschreibungen(0, 3):
print(item)
哪个为我打印:
{'Bezeichnung': 'Planung Freiland/Brücke', 'Organisation': 'Autobahnen- und Schnellstraßen-Finanzierungs-Aktiengesellschaft', 'Veröffentlicht': '08.04.2019', 'Frist': None}
{'Bezeichnung': 'Lieferung von Erdgas 2020 - 2022', 'Organisation': 'Republik Österreich (Bund), Bundesbeschaffung GmbH sowie alle weiteren Auftraggeber gemäß der den Ausschreibungsunterlagen beiliegenden Drittkundenliste, im Vergabeverfahren alle vertreten durch die Bundesbeschaffung GmbH', 'Veröffentlicht': '08.04.2019', 'Frist': '07.05.2019'}
{'Bezeichnung': 'Umbau Bahnhof Villach ', 'Organisation': 'ÖBB-Personenverkehr AG', 'Veröffentlicht': '08.04.2019', 'Frist': None}
我确定将其过滤/转换为CSV不再是问题。
使用浏览器的开发人员工具(F12)找出正在发送的其他请求参数以及它们是否与您相关。您还可以尝试使用requests
模块的Session功能进行“混合”,复制所有HTTP标头和cookie,但是鉴于这似乎是政府站点,他们可能不会介意您正在抓取他们。
答案 1 :(得分:0)
在单独的列中编写
reader = csv.DictReader(f) # open and write mode opened file
csvWriter = csv.writer(f)
existing_queries = set()
for row in reader:
if reader.line_num == 1:
continue
if row['link'] in existing_queries:
print("Already exists")
else:
csvWriter.writerow("description", "link") # will write
existing_queries.add("description", "link")
我希望这对您有帮助
答案 2 :(得分:-1)
使用csv.writer类的换行符和定界符
您可以在此处找到示例:https://docs.python.org/3/library/csv.html#writer-objects