今天为大家介绍的是关于使用Python进行Web爬取和数据提取的内容。我们首先是要清楚地了解任务。他们希望我们从中抓取数据,然后将其保存在CSV文件中,其中上面列出的我们将抓取信息:日期(“以下信息反映了终止{日期}的FMCSA管理信息系统的内容”),运行状态,合法名称,DBA名称,实际地址,邮寄地址,USDOT号,动力单元,车手。
步骤1:了解任务
我们可以提供100个DOT号码的初始设置,以确保可以轻松地刮除上面的信息,从那里我们可以提供每天要刮擦的所有DOT号码。
报告页面可以通过点或其他名称ID进行访问。每个页面都有自己的ID(点)。因此,这些点位于Excel文件中。我们必须阅读此文件并从中提取点,然后将其传递到URL以访问报告页面。
第2步:创建环境并安装依赖项
现在,我们知道了客户希望从我们这里得到什么,因此让我们创建虚拟环境,然后检查将要爬网的元素。
要创建virtualenv,请在终端中运行以下命令:
虚拟环境
然后安装BeautifulSoup(这是一个用于解析HTML和XML文档的Python包)和xlrd(这是一个用于从Excel文件读取数据并设置信息格式的库):
pip install beautifulsoup4 xlrd
步骤3:检索数据
好了,开发人员!让我们从打开项目描述的示例URL开始,刹车可以看到细分。
提示以查看示例URL
我们的第一个目标是查找-日期(“以下信息反映了终止{日期}的FMCSA管理信息系统的内容”)
以下信息反映了截止日期01/01/2020的FMCSA管理信息系统的内容。
事实是,我们无法通过特定的类名或ID来检索此元素。不幸的是,此报告页面隐藏混乱。
但是,我们可以将它们全部作为文本进行爬网,并使用RegEx提取所需的数据。
正则表达式(RegEx)是特殊的字符序列,可使用模式中保留的特殊语法来帮助您匹配或查找其他字符串或字符串集。
日期位于之间。以下信息反映了FMCSA管理信息系统的开始日期,以及..(点)。因此,要输入日期正则表达式将在这些字符串之间查找。
import re#regeximport urllib.request from urllib.request import urlopen,Requestfrom bs4 import BeautifulSoupdef crawl_data(url):
req = Request(URL,标头= {'User-Agent':'Mozilla / 5.0'})
html = urlopen(req).read()
bs = BeautifulSoup(html,'html.parser')
#查找所有粗体文本
bold_texts = bs.find_all('b')
对于b在bold_texts中:
尝试:
#在这些字符串之间看
date = re.search('以下信息反映了FMCSA管理信息系统自(。*)起的内容。',b.get_text(strip = True,分隔符=''))。group(1).strip( )
#如果正则表达式找到多个点,则在第一个点之前提取字符串
如果len(date)> 11:
日期= date.split(“。”,1)[0]
打印(日期)
除了AttributeError:
通过
好吧,如果您运行该程序,您将看到它正在打印日期。快速向您展示正则表达式的工作原理,因为我有些人想了解。
考虑以下代码:
汇入
#我们需要从字符串中提取“ coderasha”
data =“您好,我叫Coderasha。”
名称= re.search('你好我的名字是(。*)。',数据)
打印(名称)
#输出:<_sre.SRE_Match对象;span =(0,27),match ='你好,我叫Coderasha。'>
group(1)将其中正则表达式匹配的文本捕获到一个编号组中,该编号组可以与编号后向引用一起重用
汇入
#我们需要从字符串中提取“ coderasha”
data =“您好,我叫Coderasha。”
名称= re.search('你好我的名字是(。*)。',数据).group(1)
打印(名称)
#输出:coderasha
因此,我正在应用相同的逻辑来查找爬网的串行中的日期。
但是,我们必须使用RegEx再次查找数据,因为表元素没有任何特殊属性。
#获取表格内的所有文本
信息= bs.find('中心').get_text(strip =真,分隔符='')#使用RegEx查找字段
Operating = re.search('Operating Status:(。*)Out',information).group(1).strip()
legal_name = re.search('法律名称:(。*)DBA',信息).group(1).strip()
physical_address = re.search('Physical Address:(。*)Phone',information).group(1).strip()
mailing_address = re.search('邮件地址:(。*)USDOT',信息).group(1).strip()
usdot_address = re.search('USDOT号:(。*)国家运营商ID号',信息).group(1).strip()
power_units = re.search('Power Units:(。*)Drivers',information).group(1).strip()
drivers = re.search('Drivers:(。*)MCS-150表格日期',信息).group(1).strip()
步骤4:以CSV格式写入资料
抓取数据后,就该创建新的csv文件链接数据写入其中了。我更喜欢创建另一个函数来处理此操作。
导入csvdef write_csv(日期,运行,legal_name,物理地址,mailing_address,usdot_address,power_units,驱动程序):
使用open(usdot_address +'.csv',mode ='w',newline ='',encoding =“ utf-8”)作为csv_file:
字段名称= [“日期”,“运行状态”,“法律名称”,“物理地址”,“邮寄地址”,“动力装置”,“驱动程序”]
writer = csv.DictWriter(csv_file,fieldnames = fieldnames)
writer.writeheader()
writer.writerow({''Date':date,'Operating Status':Operating,'Legal_Name':legal_name,'Physical Address':physical_address,'Mailing Address':mailing_address,'Power Units:power_units,'Drivers':drivers })
CSV名称必须唯一,因此我用usdot_address或使用已抓取数据的报告页面的其他名称ID。
步骤5:读取Excel文件以抓取每个点的数据
最后一步是读取excel文件,将这些点传递到URL的末尾以访问页面。我们可以用xlrd读取Excel文件。
导入xlrd
点= [] def read_excel_file():
loc =(“ dots.xls”)
wb = xlrd.open_workbook(loc)
工作表= wb.sheet_by_index(0)
sheet.cell_value(0,0)
#Excel中的前五个点
对于我在范围(1,5)中:
#将浮点数转换为字符串并从.0清除
点= str(sheet.cell_value(i,0))。replace('。0','')
dots.append(dot)
xlrd将数字读取为浮点数,因此最好的解决方案是将数字转换为字符串并使用
更换()
删除字符串.0结尾将这些点传递到url中的方法:
对于点中的点:
crawl_data
#睡眠5秒,避免任何错误
time.sleep(5)
这是完整代码:
导入重新导入csv导入urllib.request从urllib.request导入urlopen,Requestfrom bs4导入BeautifulSoupimport xlrd导入时间
点= [] def read_excel_file():
loc =(“ dots.xls”)
wb = xlrd.open_workbook(loc)
工作表= wb.sheet_by_index(0)
sheet.cell_value(0,0)
对于我在范围(1,5)中:
点= str(sheet.cell_value(i,0))。replace('。0','')
dots.append(dot)def crawl_data(url):
req = Request(URL,标头= {'User-Agent':'Mozilla / 5.0'})
html = urlopen(req).read()
bs = BeautifulSoup(html,'html.parser')
bold_texts = bs.find_all('b')
对于b在bold_texts中:
尝试:
date = re.search('以下信息反映了FMCSA管理信息系统自(。*)起的内容。',b.get_text(strip = True,分隔符=''))。group(1).strip( )
如果len(date)> 11:
日期= date.split(“。”,1)[0]
打印(日期)
除了AttributeError:
通过
信息= bs.find('中心').get_text(strip =真,分隔符='')
Operating = re.search('Operating Status:(。*)Out',information).group(1).strip()
legal_name = re.search('法律名称:(。*)DBA',信息).group(1).strip()
physical_address = re.search('Physical Address:(。*)Phone',information).group(1).strip()
mailing_address = re.search('邮件地址:(。*)USDOT',信息).group(1).strip()
usdot_address = re.search('USDOT号:(。*)国家运营商ID号',信息).group(1).strip()
power_units = re.search('Power Units:(。*)Drivers',information).group(1).strip()
drivers = re.search('Drivers:(。*)MCS-150表格日期',信息).group(1).strip()
def write_csv(日期,运作,法定名称,物理地址,mailing_address,usdot_address,power_units,驱动程序)def write_csv(日期,运作,合法名称,物理地址,mailing_address,usdot_address,power_units,驱动程序):
使用open(usdot_address +'.csv',mode ='w',newline ='',encoding =“ utf-8”)作为csv_file:
字段名称= [“日期”,“运行状态”,“法律名称”,“物理地址”,“邮寄地址”,“动力装置”,“驱动程序”]
writer = csv.DictWriter(csv_file,fieldnames = fieldnames)
writer.writeheader()
writer.writerow({''Date':date,'Operating Status':Operating,'Legal_Name':legal_name,'Physical Address':physical_address,'Mailing Address':mailing_address,'Power Units:power_units,'Drivers':drivers })
read_excel_file()
以点为单位打印(点):
crawl_data
time.sleep(5)
任务完成!
以上就是关于使用Python进行Web爬取和数据提取的全部内容,想了解更多关于Python的信息,请继续关注我们吧。