2021SC@SDUSC
目录
一、摘要
二、“app.py”文件核心代码分析
1.部分1
2.部分2?
3.部分3?
4.部分4
5.部分5
?三、总结
一、摘要
本篇博客将对最后一个项目“SIPO专利审查”的核心文件“app.py”进行代码分析,这也将是整个“ECommerceCrawlers”的最后一篇博客!
二、“app.py”文件核心代码分析
1.部分1
class TextQthread(QThread):
show_in_textBrowser = pyqtSignal(str)
def __init__(self, parent=None):
super().__init__()
self.url = 'http://cpquery.cnipa.gov.cn/'
self.ori_url = ''
self.shenqingh = ''
self.browser = ''
self.data_csv = ''
self.length = 0
def creatfile(self):
header = ['ID', '查询结果', '专利类型', '申请号/专利号', '发明名称', '申请人', '申请日', '授权公告日', '主分类号', '案件状态',
'应缴费用种类', '应缴金额', '应缴截止日', '应缴状态', '已缴费用种类', '已缴金额', '缴费日期', '缴费人姓名', '票据号码(收据号)']
if not os.path.exists('专利审查结果.csv'):
with open('专利审查结果.csv', 'a', newline='', encoding='utf8') as f:
writer = csv.writer(f)
writer.writerow(header)
def inputdata(self):
if not os.path.exists('待查账号.csv'):
self.show_in_textBrowser.emit(
'待查账号.csv 文件不存在! 请关闭程序后, 在本文件夹创建本文件!\n')
return False
else:
self.csv_data = pd.read_csv('待查账号.csv')
_length = len(self.csv_data)
self.show_in_textBrowser.emit(
'待查账号.csv 文件含账号个数: {}'.format(_length))
if _length >= 250:
self.length = 250
elif _length == 0:
return False
else:
self.length = _length
return True
def __init__(self, parent=None): ? ? ? ? super().__init__() ? ? ? ? self.url = 'http://cpquery.cnipa.gov.cn/' ? ? ? ? self.ori_url = '' ? ? ? ? self.shenqingh = '' ? ? ? ? self.browser = '' ? ? ? ? self.data_csv = '' ? ? ? ? self.length = 0
该_init_函数是作为初始化函数,完成一些变量的初始化定义过程,ori_url,shenqingh等变量设为空值,self.url设置为http://cpquery.cnipa.gov.cn/,即“中国及多国专利审查信息查询”网站的首页url。
?def creatfile(self): ? ? ? ? header = ['ID', '查询结果', '专利类型', '申请号/专利号', '发明名称', '申请人', '申请日', '授权公告? ? ? ? ? ? ? ? ? ? ? ? ? ?日', '主分类号', '案件状态',?'应缴费用种类', '应缴金额', '应缴截止日', '应缴状态', '已? ? ? ? ? ? ? ? ? ? ? ? ? ?缴费用种类', '已缴金额', '缴费日期', '缴费人姓名', '票据号码(收据号)'] ? ? ? ? if not os.path.exists('专利审查结果.csv'): ? ? ? ? ? ? with open('专利审查结果.csv', 'a', newline='', encoding='utf8') as f: ? ? ? ? ? ? ? ? writer = csv.writer(f) ? ? ? ? ? ? ? ? writer.writerow(header)
creatfile函数是创建一个专利审查结果的csv文件,用来保存查询到的专利审查信息,自定义了问价的header信息,包括'ID', '查询结果', '专利类型', '申请号/专利号', '发明名称', '申请人', '申请日', '授权公告日', '主分类号', '案件状态',?'应缴费用种类', '应缴金额', '应缴截止日', '应缴状态', '已缴费用种类', '已缴金额', '缴费日期', '缴费人姓名', '票据号码(收据号)'信息。
def inputdata(self): ? ? ? ? if not os.path.exists('待查账号.csv'): ? ? ? ? ? ? self.show_in_textBrowser.emit( ? ? ? ? ? ? ? ? '待查账号.csv 文件不存在! 请关闭程序后, 在本文件夹创建本文件!\n') ? ? ? ? ? ? return False ? ? ? ? else: ? ? ? ? ? ? self.csv_data = pd.read_csv('待查账号.csv') ? ? ? ? ? ? _length = len(self.csv_data) ? ? ? ? ? ? self.show_in_textBrowser.emit( ? ? ? ? ? ? ? ? '待查账号.csv 文件含账号个数: {}'.format(_length)) ? ? ? ? ? ? if _length >= 250: ? ? ? ? ? ? ? ? self.length = 250 ? ? ? ? ? ? elif _length == 0: ? ? ? ? ? ? ? ? return False ? ? ? ? ? ? else: ? ? ? ? ? ? ? ? self.length = _length ? ? ? ? ? ? return True
inputdata函数是与输入数据有关(输入数据即存在于待查账号.csv中的那些专利号信息)。通过if条件判断若不存在“待查账号.csv”的路径,则会创建并且提示。若该文件存在,则会输出该文件中包含的账号个数。
2.部分2?
def dealresult1(self):
List = []
WebDriverWait(self.browser, waittime).until(
EC.presence_of_element_located((By.NAME, 'record:shenqingh')))
time.sleep(0.5)
try:
_record_zhuanlilx = self.browser.find_element_by_xpath(
'//div[@class="content_boxx"]/table/tbody/tr/td[1]').get_attribute('textContent')
_record_shenqingh = self.browser.find_element_by_xpath(
'//div[@class="content_boxx"]/table/tbody/tr/td[2]')
_record_name = self.browser.find_element_by_xpath(
'//div[@class="content_boxx"]/table/tbody/tr/td[3]').get_attribute('textContent')
_record_shenqingrxm = self.browser.find_element_by_xpath(
'//div[@class="content_boxx"]/table/tbody/tr/td[4]').get_attribute('textContent')
_record_shenqingr = self.browser.find_element_by_xpath(
'//div[@class="content_boxx"]/table/tbody/tr/td[5]').get_attribute('textContent')
_record_shouquanggr = self.browser.find_element_by_xpath(
'//div[@class="content_boxx"]/table/tbody/tr/td[6]').get_attribute('textContent')
_record_zhufenlh = self.browser.find_element_by_xpath(
'//div[@class="content_boxx"]/table/tbody/tr/td[7]').get_attribute('textContent')
zhuanlilx = _record_zhuanlilx.strip()
shenqingh = _record_shenqingh.get_attribute('textContent').strip()
name = _record_name.strip()
shenqingrxm = _record_shenqingrxm.strip()
shenqingr = _record_shenqingr.strip()
shouquanggr = _record_shouquanggr.strip()
zhufenlh = _record_zhufenlh.strip()
List = [self.shenqingh, '有', zhuanlilx, shenqingh, name, shenqingrxm,
shenqingr, shouquanggr, zhufenlh]
try:
_record_shenqingh.click()
except Exception as e:
pass
finally:
return List
except Exception as e:
return [self.shenqingh, '无', ]
? ? ? ? ? ? _record_zhuanlilx = self.browser.find_element_by_xpath( ? ? ? ? ? ? ? ? '//div[@class="content_boxx"]/table/tbody/tr/td[1]').get_attribute('textContent') ? ? ? ? ? ? _record_shenqingh = self.browser.find_element_by_xpath( ? ? ? ? ? ? ? ? '//div[@class="content_boxx"]/table/tbody/tr/td[2]') ? ? ? ? ? ? _record_name = self.browser.find_element_by_xpath( ? ? ? ? ? ? ? ? '//div[@class="content_boxx"]/table/tbody/tr/td[3]').get_attribute('textContent') ? ? ? ? ? ? _record_shenqingrxm = self.browser.find_element_by_xpath( ? ? ? ? ? ? ? ? '//div[@class="content_boxx"]/table/tbody/tr/td[4]').get_attribute('textContent') ? ? ? ? ? ? _record_shenqingr = self.browser.find_element_by_xpath( ? ? ? ? ? ? ? ? '//div[@class="content_boxx"]/table/tbody/tr/td[5]').get_attribute('textContent') ? ? ? ? ? ? _record_shouquanggr = self.browser.find_element_by_xpath( ? ? ? ? ? ? ? ? '//div[@class="content_boxx"]/table/tbody/tr/td[6]').get_attribute('textContent') ? ? ? ? ? ? _record_zhufenlh = self.browser.find_element_by_xpath( ? ? ? ? ? ? ? ? '//div[@class="content_boxx"]/table/tbody/tr/td[7]').get_attribute('textContent') ? ? ? ? ? ? zhuanlilx = _record_zhuanlilx.strip() ? ? ? ? ? ? shenqingh = _record_shenqingh.get_attribute('textContent').strip() ? ? ? ? ? ? name = _record_name.strip() ? ? ? ? ? ? shenqingrxm = _record_shenqingrxm.strip() ? ? ? ? ? ? shenqingr = _record_shenqingr.strip() ? ? ? ? ? ? shouquanggr = _record_shouquanggr.strip() ? ? ? ? ? ? zhufenlh = _record_zhufenlh.strip() ? ? ? ? ? ? List = [self.shenqingh, '有', zhuanlilx, shenqingh, name, shenqingrxm, ? ? ? ? ? ? ?shenqingr, shouquanggr, zhufenlh]
?这里是运用xpath数据解析技术对获取到的网站内容进行提取,将这些提取出来的数据存进_record_zhuanlilx和_record_shenqingh等变量里,后面再用strip函数对这些变量作过滤保存为去掉“_record_”的变量。
strip()?方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列。 注意:该方法只能删除开头或是结尾的字符,不能删除中间部分的字符
例:str.strip([chars])
参数——chars -- 移除字符串头尾指定的字符序列。 返回值——返回移除字符串头尾指定的字符生成的新字符串。
最后的List是将这些获取到的数据封装成一个完整的对象,用于后续的存储操作。
3.部分3?
def dealresult2(self, List):
WebDriverWait(self.browser, waittime).until(
EC.presence_of_element_located((By.NAME, 'record_zlx:anjianywzt')))
time.sleep(0.5)
try:
anjianywzt = self.browser.find_element_by_name(
'record_zlx:anjianywzt').get_attribute('title')
List.append(anjianywzt)
except Exception as e:
List.append('')
finally:
self.browser.find_element_by_xpath(
'//div[@class="tab_list"]/ul/li[3]').click()
return List
? ? ? ? try: ? ? ? ? ? ? anjianywzt = self.browser.find_element_by_name( ? ? ? ? ? ? ? ? 'record_zlx:anjianywzt').get_attribute('title') ? ? ? ? ? ? List.append(anjianywzt)
将上面得到的list作为函数参数输入,对self.browser调用find_element_by_name方法获取对应name的title信息并存为anjianwzt。?
?4.部分4
def dealresult3(self, List):
WebDriverWait(self.browser, waittime).until(
EC.presence_of_element_located((By.NAME, 'record_yingjiaof:yingjiaofydm')))
time.sleep(0.5)
try:
yingjiaofydm = self.browser.find_element_by_name(
'record_yingjiaof:yingjiaofydm').get_attribute('title')
shijiyjje = self.browser.find_element_by_name(
'record_yingjiaof:shijiyjje').get_attribute('title')
jiaofeijzr = self.browser.find_element_by_name(
'record_yingjiaof:jiaofeijzr').get_attribute('title')
feiyongzt = self.browser.find_element_by_name(
'record_yingjiaof:feiyongzt').get_attribute('title')
L1 = [yingjiaofydm, shijiyjje, jiaofeijzr, feiyongzt]
except Exception as e:
L1 = ['', '', '', '']
finally:
List += L1
try:
feiyongzldm = self.browser.find_element_by_name(
'record_yijiaof:feiyongzldm').get_attribute('title')
jiaofeije = self.browser.find_element_by_name(
'record_yijiaof:jiaofeije').get_attribute('title')
jiaofeisj = self.browser.find_element_by_name(
'record_yijiaof:jiaofeisj').get_attribute('title')
jiaofeirxm = self.browser.find_element_by_name(
'record_yijiaof:jiaofeirxm').get_attribute('title')
shoujuh = self.browser.find_element_by_name(
'record_yijiaof:shoujuh').get_attribute('title')
L2 = [feiyongzldm, jiaofeije, jiaofeisj, jiaofeirxm, shoujuh]
except Exception as e:
L2 = ['', '', '', '', '']
finally:
List += L2
return List
该部分同样是对self.browser进行调用find_element_by_name方法用一个name获取到对应的title信息并存为对应变量,类似于?yingjiaofydm(应缴费用),shijiyjje(实际应缴)等等。最后将这些存储好的变量封装成对应的L1和L2对象,并将这些对象加入之前创建的List对象中,最后返回该List。
5.部分5
def run(self):
flg = self.inputdata()
if flg:
self.creatfile()
self.show_in_textBrowser.emit('专利审查结果.csv 文件创建成功/已经存在')
self.show_in_textBrowser.emit('----------------------\n')
self.show_in_textBrowser.emit(
'请在自动启动的 Firefox 浏览器中\n登录 并 点击到查询界面\n然后, 交给自动控制程序!!!')
self.show_in_textBrowser.emit('======================\n')
self.browser = webdriver.Firefox()
self.browser.get(self.url)
WebDriverWait(self.browser, 600000).until(
EC.presence_of_element_located((By.ID, 'authImg'))) # 等待验证码已加载出来
self.ori_url = self.browser.current_url
self.show_in_textBrowser.emit('======================\n')
self.show_in_textBrowser.emit('开始自动查询(每个账号每次限制查询 250 次):\n')
for i in range(self.length):
self.shenqingh = self.csv_data.loc[i, 'ID'].replace(
'CN', '').replace('.', '')
self.searchPage(self.shenqingh)
List = self.dealresult1()
if len(List) == 2:
self.writecsv(List)
self.show_in_textBrowser.emit(
'{}/{}\tID: {}\t未检索到'.format(i+1, self.length, self.shenqingh))
self.browser.get(self.ori_url)
else:
List = self.dealresult2(List)
List = self.dealresult3(List)
self.writecsv(List)
self.show_in_textBrowser.emit(
'{}/{}\tID: {}\t写入成功'.format(i+1, self.length, self.shenqingh))
self.browser.get(self.ori_url)
self.browser.get(self.url)
该部分是对应的运行函数部分。
self.creatfile() ? ? ? ? ? ? self.show_in_textBrowser.emit('专利审查结果.csv 文件创建成功/已经存在') ? ? ? ? ? ? self.show_in_textBrowser.emit('----------------------\n') ? ? ? ? ? ? self.show_in_textBrowser.emit( ? ? ? ? ? ? ? ? '请在自动启动的 Firefox 浏览器中\n登录 并 点击到查询界面\n然后, 交给自动控制程序!!!') ? ? ? ? ? ? self.show_in_textBrowser.emit('======================\n')
这里对应的是之前的可视化ui显示的提示内容,如图:
self.browser = webdriver.Firefox() self.browser.get(self.url)
这里对应的操作是“启动/登录”。
启动登录之后到达搜索页面进行搜索操作,开始对账号进行自动查询操作(每个账号限制查询250次)
?for i in range(self.length): ? ? ? ? ? ? ? ? self.shenqingh = self.csv_data.loc[i, 'ID'].replace( ? ? ? ? ? ? ? ? ? ? 'CN', '').replace('.', '') ? ? ? ? ? ? ? ? self.searchPage(self.shenqingh) ? ? ? ? ? ? ? ? List = self.dealresult1() ? ? ? ? ? ? ? ? if len(List) == 2: ? ? ? ? ? ? ? ? ? ? self.writecsv(List) ? ? ? ? ? ? ? ? ? ? self.show_in_textBrowser.emit( ? ? ? ? ? ? ? ? ? ? ? ? '{}/{}\tID: {}\t未检索到'.format(i+1, self.length, self.shenqingh)) ? ? ? ? ? ? ? ? ? ? self.browser.get(self.ori_url) ? ? ? ? ? ? ? ? else: ? ? ? ? ? ? ? ? ? ? List = self.dealresult2(List) ? ? ? ? ? ? ? ? ? ? List = self.dealresult3(List) ? ? ? ? ? ? ? ? ? ? self.writecsv(List) ? ? ? ? ? ? ? ? ? ? self.show_in_textBrowser.emit( ? ? ? ? ? ? ? ? ? ? ? ? '{}/{}\tID: {}\t写入成功'.format(i+1, self.length, self.shenqingh)) ? ? ? ? ? ? ? ? ? ? self.browser.get(self.ori_url)
该for循环是run函数的核心,它主要是对所有的账号进行查询操作,如果查询不到结果,则会提示“未检索到”的信息,若查询到正确结果,则会提示某个账号“写入成功”。
?三、总结
通过对本次“SIPO专利审查”项目的代码分析,让我对这种需要登录才能进行查询的网站爬取有了更深的了解,也掌握了对应的操作,收获了很多知识。
同时本篇博客也是整个“ECommerceCrawlers”的最后一篇博客了,通过这几个月对四个爬虫项目的代码分析,我一边学习相对应的爬虫知识一边去分析这些代码,这段时间对爬虫项目收获了很多很多知识,也让我对爬虫产生了更加浓厚的兴趣,受益匪浅,我也会在以后的日子对爬虫进行更深入的研究。
|